跨域及解决方案

同源策略
  说到跨域,我们不得不说说同源策略,因为造成前端跨域问题的“罪魁祸首”就是浏览器的同源策略
那么什么是同源呢?
  按照浏览器同源策略,不同的源是不能进行请求操作的;
  两个页面只要满足相同的协议,域名,端口,就表示两个页面之间有相同的源,这里就不举例子说明了
  知道了什么是同源策略,因为不同源造成的请求错误,发送的请求会跨域,在开发中经常遇到

怎么解决跨域?
  解决跨域问题是开发者必备的技能,不管在开发环境还是生产环境,跨域都会经常遇到
  这里主要介绍三种常见的解决方法,JSONP,CORS(跨域资源共享)以及反向代理


  1、JSONP(JSON with Padding)
    首先要说明的是JSONP只支持get请求,支持老式浏览器
    具体怎么实现的?
    我们都知道script标签可以引入不同源的js文件,而且引入的js会立即执行

demo.htm 

<!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>
   <script src='http:www.jsthin.com/js/demo.js'></script>
 </body>
</html>

demo.js

console.log('我是src请求的文件,我马上被执行了')

  这时浏览器控制台会打印出‘我是src请求的文件,我马上被执行了’,再来看看下面的代码

demo.html

<body>
    <script>
        function printf(data) {
            console.log(data)
        }
    </script>
    <script src='http:www.jsthin.com/js/demo.js'></script>
</body>

demo.js

printf('我是jsonp请求回来的js文件,我被执行了')

  我们也可以看到浏览器控制台输出了‘我是jsonp请求回来的js文件,我被执行了’,JSONP就是使用这样的原理实现的跨域请求,将数据data通过函数参数的方式传递

  接下来我们看一个完整的JSONP应用

<body>
  <button onclick=sendRequest"('printf')">JSONP跨域请求</button>
  <script>
    function printf(data) {    
      let jsonpScript = document.getElementsByClassName('jsonpScript')[0];
      document.body.removeChild(jsonpScript);
    }
    function sendRequest(callback) {
      let jsonpScript = document.createElement('script');
      jsonpScript.src = `http://www.jsthin.com/js/demo.js?callback=${callback}`;
      jsonpScript.className = 'jsonpScript';
      document.body.appendChild(jsonpScript);
    }
  </script>
</body>
printf({
    name: 'jsthin',
    age: 20
})

  

  2.、CORS(Cross-origin resource sharing)

    普通请求跨域:后端设置Cross-origin resource sharing即可,前端不需要设置,若需要带cookie,前后端都需要设置

    这里说明一下前端的设置

    • 原生ajax
      // 前端设置是否带cookie
      xhr.withCredentials = true;
    • jQuery的ajax
      $.ajax({
          ...
         xhrFields: {
             withCredentials: true    // 前端设置是否带cookie
         },
         crossDomain: true,   // 会让请求头中包含跨域的额外信息,但不会含cookie
          ...
      });
    • axios
      axios.defaults.withCredentials = true
    • vue-resource
      Vue.http.options.credentials = true

    

  3、nginx代理跨域

server{
    # 监听8080端口
    listen 8080;
    # 域名是localhost
    server_name localhost;
    #凡是localhost:8080/api这个样子的,都转发到真正的服务端地址http://www.b.com:8080 
    location ^~ /api {
        proxy_pass http://www.b.com:8080;
    }    
}
原文地址:https://www.cnblogs.com/linhongjie/p/12832760.html