跨域:是由于浏览的同源策略限制出现的。同源策略会阻止一个域的脚本和另外一个域的内容进行交互。同源是指两个页面具有相同的协议(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
}
})
}