天天看点

跨域请求(JSONP、CORS、webpack的本地代理、proxy代理)

 跨域:是由于浏览的同源策略限制出现的。同源策略会阻止一个域的脚本和另外一个域的内容进行交互。同源是指两个页面具有相同的协议(protocol)、主机(host)和端口号(port)。当请求的url的协议、域名、端口三者之间任意一个与当前页面的url不同就为跨域。

非同源的限制有:

1、无法向非同源的地址发送AJAX请求

2、无法读取非同源的Cookie、LocalStorage和IndexedDB

3、无法接触非同源网页的DOM

JSONP实现跨域

JSONP是服务器与客户端跨域通信的常用方法,是民间自创的的一种方法,只支持get请求,不支持post请求。

核心原理是:通过script元素,向服务器请求JSON数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。

实现方式:

① 原生的方式

<script src="http://test.com/data.php?callback=dosomething"></script>
// 向服务器test.com发出请求,该请求的查询字符串有一个callback参数,用来指定回调函数的名字
 
// 处理服务器返回回调函数的数据
<script type="text/javascript">
    function dosomething(res){
        // 处理获得的数据
        console.log(res.data)
    }
</script>
           

② 通过jQuery ajax

jQuery.ajax({
    url: 'http://www.test.com:8080/login',
    type: 'get',
    dataType: 'jsonp',  // 请求方式为jsonp
    jsonpCallback: "handleCallback",    // 自定义回调函数名
    data: {}
});
           

③ Vue.js

this.$http.jsonp('http://www.domain2.com:8080/login', {
    params: {},
    jsonp: 'handleCallback'
}).then((res) => {
    console.log(res); 
})
           

CORS实现跨域

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

1、普通的跨域请求:只需要服务端设置Access-Control-Allow-Origin

2、带cookie跨域请求:前后端都需要进行设置

【前端设置】根据xhr.withCredentials字段判断是否带有cookie

①原生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);
    }
};
           

②jQuery ajax

jQuery.ajax({
   url: 'http://www.test.com:8080/login',
   type: 'get',
   data: {},
   xhrFields: {
       withCredentials: true    // 前端设置是否带cookie
   },
   crossDomain: true,   // 会让请求头中包含跨域的额外信息,但不会含cookie
});
           

③vue-resource

Vue.http.options.credentials = true
           

④axios

axios.defaults.withCredentials = true
           

webpack本地代理实现跨域

在webpack.config,js中利用WebpackDevServer配置本地的代理。

可以看成是在本地生成一个服务器,可以任意设置本地的服务器的接口。若将此服务器的接口与目标服务器的接口设置成一样,就相当于没有跨域,从而达到跨域的目的。

devServer: {
        port: 8080,
        proxy: {
            "/api": {
              target: "http://192.168.25.20:8088" // 前端需要跨域的后端接口
            }
        }
    }
           

Proxy代理

proxy是ES6中就存在的,用于修改某些操作的默认行为,可以理解成在目标对象前设一个拦截层,因此也叫“代理器”。

ES6原生提供的Proxy语法很简单。

let proxy = new Proxy(target, handler)
           

Vue中的proxy代理

Vue框架开发的时候,会遇到跨域的问题,可在config/index.js里面配置proxyTable内容,使用proxy代理。

proxyTable: {
      '/api': {
        target: 'http://xxx.com:8080', // 你要代理的域名和端口号,要加上http
        changeOrigin: true, // 跨域
        pathRewrite: {
          '^/api': '/api' // 这里用‘/api’代替target里面的地址,组件中调用接口时直接用api代替 比如我要调用'http://xxx.com:8080/api/NEWS/getNews.json?page=1&pageSize=10
',直接写‘/api/NEWS/getNews.json?page=1&pageSize=10’即可
        }
      }
           

然后在axios中请求

getNewsList() {
      const url = '/api/NEWS/getNews.json?page=1&pageSize=10'
      axios.get(url)
        .then((res) => {
          res = res.data
          if (res.state) {
            this.news = res.result
          }
        })
    }
    
           

继续阅读