• 浏览器的跨域问题


    为什么要跨域

    • 同源策略
      浏览器的同源策略:是浏览器的一个安全功能,不同源的网页脚本在没有明确授权的情况下,不能读写对方的资源,也就是会阻止一个域的javascript脚本和另外一个域的内容进行交互

    • 同源
      同源指的是(“协议+域名+端口”)三者相同

    跨域问题

    解释:使用AJAX技术(XML HttpRequest对象),从一个网页去请求另一个网页的资源时,违反了浏览器的同源策略,限制引起的安全问题。

    解决跨域的思路:

    • 根源上解决,不使用ajax技术
    • 授权跨域资源共享

    解决跨域(列举三个最常用的CORS、JSONP和代理服务器nginx)

    CORS

    CORS 是跨域资源分享(Cross-Origin Resource Sharing)的缩写。它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。

    • 普通跨域请求只需要服务端设置 Access-Control-Allow-Origin
    • 带cookie的跨域请求前后端都需要设置

    【前端设置】根据xhr.withCredentials字段判断是否带有cookie
    1.原生ajax写法

    var xhr = new XMLHttpRequest(); // IE8/9需用window.XDomainRequest兼容
     
    // 前端设置是否带cookie
    xhr.withCredentials = true;
     
    xhr.open('post', 'http://www.domain2.com:8080/login', true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.send('user=admin');
     
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4 && xhr.status == 200) {
            alert(xhr.responseText);
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.jQuery ajax

    
    $.ajax({
       url: 'http://www.test.com:8080/login',
       type: 'get',
       data: {},
       xhrFields: {
           withCredentials: true    // 前端设置是否带cookie
       },
       crossDomain: true,   // 会让请求头中包含跨域的额外信息,但不会含cookie
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3.vue-resource

    Vue.http.options.credentials = true
    
    • 1

    4.axios

    axios.defaults.withCredentials = true
    
    • 1

    5.fetch()方法实现

    <script>
      fetch("http://127.0.0.1:35911", // url地址
      {method: "GET"}) // 用服务器允许的方法请求
      .then{ resonse => response.json{} } // 
      .then{ data => console.log{data.like} };
     </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    fetch方法的node.js后台设置

    cosnt express = require{'express '};
    const cors = require{'cors'};
    const app = express{};
    
    app.use(
      cors ({
        origin:"*", // 允许所有源进行访问
        methods:['GET','POST'] // 定义可以访问的方法
      })
    );
    
    app.get('/',{request,response} =>{
      response.json(
        {"name:"hello","wrold"}
      );
    });
    
    app.listen(35911);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    【服务端设置】
    服务器端对于CORS的支持,主要是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。

    1.Nodejs后台

    var http = require('http');
    var server = http.createServer();
    var qs = require('querystring');
     
    server.on('request', function(req, res) {
        var postData = '';
     
        // 数据块接收中
        req.addListener('data', function(chunk) {
            postData += chunk;
        });
     
        // 数据接收完毕
        req.addListener('end', function() {
            postData = qs.parse(postData);
     
            // 跨域后台设置
            res.writeHead(200, {
                'Access-Control-Allow-Credentials': 'true',     // 后端允许发送Cookie
                'Access-Control-Allow-Origin': 'http://www.domain1.com',    // 允许访问的域(协议+域名+端口)
                /* 
                 * 此处设置的cookie还是domain2的而非domain1,因为后端也不能跨域写cookie(nginx反向代理可以实现),
                 * 但只要domain2中写入一次cookie认证,后面的跨域接口都能从domain2中获取cookie,从而实现所有的接口都能跨域访问
                 */
                'Set-Cookie': 'l=a123456;Path=/;Domain=www.domain2.com;HttpOnly'  // HttpOnly的作用是让js无法读取cookie
            });
     
            res.write(JSON.stringify(postData));
            res.end();
        });
    });
     
    server.listen('8080');
    console.log('Server is running at port 8080...');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    2.PHP后台

    <?php
     header("Access-Control-Allow-Origin:*");
    
    • 1
    • 2
    JSONP技术原理

    JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性好(兼容低版本IE),缺点是只支持get请求,不支持post请求。

    核心思想:网页通过添加一个