跨域问题的解决方案

247 阅读4分钟

什么是跨域:

  • 浏览器在发送Ajax请求时,只接收同域服务器响应的数据资源;那么什么才算同域呢?很简单,协议、域名、端口全部相同才算同一域下,三个条件有一个不一致,都不算同域,既跨域。

同源策略,也叫跨域禁止策略

  • 阻止从一个域上加载的脚本,获取或操作另一个域上的资源;

实际操作:

  • 启动两个端口的服务器:

  • 访问8000端口的服务器获取页面,页面中使用 ajax 向9000端口的服务器发送请求;

jsonp

  • Web页面上调用js文件时则不受是否跨域的影响 (不仅如此,我们还发现凡是拥有"src"这个属性的标签都拥有跨域的能力,比如script、img、iframe); src 的能力就是把远程的数据资源加载到本地(图片、JS代码等);

如何使用JSONP

  • 就是在远程服务器上设法动态的把数据装进js格式的文本代码段中,供客户端调用和进一步处理; 在前台通过动态添加script标签及src属性,表面看上去与ajax极为相似,但是,这和ajax并没有任何关系; 为了便于使用及交流,逐渐形成了一种 非正式传输协议,人们把它称作 JSONP

  • 该协议的一个要点就是允许用户传递一个callback参数给服务端, 然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据, 这样客户端就可以随意定制自己的函数来自动处理返回数据了。

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
</body>
<!-- jsonp的核心:利用src的属性发送请求,服务器返回js代码调用前端页面写好的函数 -->
<script>
    function backData(data){
        alert(data);
    }
</script>
<!-- 返回的是:backData(123) -->
<!-- 1.核心写法 -->
<script src="http://127.0.0.1:9000/">

// <!-- 2.函数名传进去在后台就不用知道你外面的函数名了 -->
// <!-- <script src="http://127.0.0.1:9000/getjson?callback=backData"> -->
  
</script>
</html>

8000服务器:

var fs = require('fs');
var url = require('url');
var http = require('http');


var server = http.createServer();

server.listen(8000, function () {
    console.log('8000启动成功!')
})

server.on('request', function (req, res) {
    var urls = url.parse(req.url, true);

    if (req.method == 'GET') {
        if (urls.pathname == '/') {

        } else if (urls.pathname == '/gets') {

            res.end('');
        } else {

            fs.readFile('.' + urls.pathname, function (err, data_str) {
                if (!err) {
                    res.end(data_str);
                } else {
                    res.end('')
                }
            })

        }

    } else if (req.method == 'POST') {

    }

})

9000服务器

var fs = require('fs');
var url = require('url');
var http = require('http');


var server = http.createServer();

server.listen(9000, function () {
    console.log('9000启动成功!')
})

server.on('request', function (req, res) {
    var urls = url.parse(req.url, true);

    if (req.method == 'GET') {
        //1.核心写法
        if (urls.pathname == '/') {
            var num = "123";
            // var num = "文字";  也不行
            res.end('backData('+ num+')');

        } else if (urls.pathname == '/gets') {

            res.end('浏览器显示出来了');
            //2.函数名不用知道
        }else if(urls.pathname == '/getjson'){

            var str ='函数名后台我不用知道';
            //str没有输出
            // res.end(urls.query.callback+'('+str+')');
            //url可以达到函数名  因为它是通过url地址传过来的
            res.end(urls.query.callback+'('+'123'+')');
            

        } else {

            fs.readFile('.' + urls.pathname, function (err, data_str) {
                if (!err) {
                    res.end(data_str);
                } else {
                    res.end('');
                }
            })

        }

    } else if (req.method == 'POST') {
        //post请求
        if (urls.pathname == '/posts') {
            var d = '';

            req.on('data', function (post_data) {
                d += post_data;
            })

            req.on('end', function () {

                var obj = require('querystring').parse(d);

                if (obj.name == 'admin') {
                    res.end('repeat')
                } else {
                    res.end('norepeat')

                }

            })


        }
    }


})

第二种:跨域资源共享( CORS)机制

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
 
<input type="button"value="按钮" >

</body>

<script>
     document.getElementsByTagName('input')[0].onclick = function(){
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function(){
            if(xhr.readyState== 4 ){
                alert(xhr.responseText);
            }
        }
        //简单的请求
        // xhr.open('get','http://127.0.0.1:9000/getcors');
        //请求方法:
        xhr.open('delete','http://127.0.0.1:9000/getcors');
        //
        // xhr.setRequestHeader('get','http://127.0.0.1:9000/getcors');
        //请求头
        // xhr.setRequestHeader('kkkkk','http://127.0.0.1:9000/getcors');

        xhr.send();
    }

</script>
</html>

8000:服务器

var fs = require('fs');
var url = require('url');
var http = require('http');


var server = http.createServer();

server.listen(8000, function () {
    console.log('8000启动成功!')
})

server.on('request', function (req, res) {
    var urls = url.parse(req.url, true);

    if (req.method == 'GET') {
        if (urls.pathname == '/') {
          

        } else if (urls.pathname == '/gets') {

            res.end('');
        } else {

            fs.readFile('.' + urls.pathname, function (err, data_str) {
                if (!err) {
                    res.end(data_str);
                } else {
                    res.end('')
                }
            })

        }

    } else if (req.method == 'POST') {

    }

})

9000:服务器

var fs = require('fs');
var url = require('url');
var http = require('http');


var server = http.createServer();
//都需要有的


server.listen(9000, function () {
    console.log('9000启动成功!')
})

server.on('request', function (req, res) {
    var urls = url.parse(req.url, true);

    //写到这里:
    res.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:8000');
    if (req.method == 'GET') {
        
        if (urls.pathname == '/') {
          
            

        } else if (urls.pathname == '/getcors') {
            //返回之前就加请求头
            // res.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:8000');
            res.end('123456789');
           
        }else {

            fs.readFile('.' + urls.pathname, function (err, data_str) {
                if (!err) {
                    res.end(data_str);
                } else {
                    res.end('');
                }
            })

        }

    } else if (req.method == 'POST') {
        //post请求
        if (urls.pathname == '/posts') {
            var d = '';

            req.on('data', function (post_data) {
                d += post_data;
            })

            req.on('end', function () {

                var obj = require('querystring').parse(d);

                if (obj.name == 'admin') {
                    res.end('repeat')
                } else {
                    res.end('norepeat')

                }

            })


        }
    }else if(req.method == 'OPTIONS'){
        //是否允许你发什么类型的请求头过来
        //'Access-Control-Allow-Headers' ,'DELETE还有很多可以加'
        // res.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:8000');
       
        res.setHeader('Access-Control-Allow-Methods','DELETE');
        res.end('');
    }else if(req.method == 'DELETE'){
        res.end('1335881694');

    }else{

    }


})