跨域:是由于浏览的同源策略限制出现的。同源策略会阻止一个域的脚本和另外一个域的内容进行交互。同源是指两个页面具有相同的协议(protocol)、主机(host)和端口号(port)。当请求的url的协议、域名、端口三者之间任意一个与当前页面的url不同就为跨域。
非同源的限制有:
1、无法向非同源的地址发送AJAX请求
2、无法读取非同源的Cookie、LocalStorage和IndexedDB
3、无法接触非同源网页的DOM
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是跨域资源共享(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.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 } }) }