前端跨域问题笔记

一、含义:当一个请求 url 的协议、域名、端口三者之间任意一个与当前页面 url 不同即为跨域

二、同源策略:

就是同域名,同端口,同协议

例如:如果你有一个服务器 A,你所需要的 script,css,php 文件都在服务器 A,

你写的 html 也在服务器 A 上,然后运行,出现了效果,如果你想在另一台电脑上运行你的项目(注意另一台电脑无论有没有开启服务器,效果还是会显示出来的),只要把你写在服务器 A 上的协议,域名,端口以及你的项目名称复制下来,在另一台电脑上运行,同样会出现相同的效果,这就实现了同源。

简单来说,就是你的协议,域名,端口甚至项目名称都一样,不同电脑都能实现同样的效果。

无论是同台电脑,还是不同台电脑,与是不是同一台电脑没有关系,都能实现跨域

和同源。

三、解决跨域

  1. 设置 document.domain 解决无法读取非同源网页的 Cookie 的问题

因为浏览器是通过 document.domain 属性来检查两个页面是否同源,因此只要通

过设置相同的 document.domain,两个页面就可以共享 Cookie(此方案仅限主域相同,子域不同的跨域应用场景。)

//两个页面都设置

document.domain = 'test.html';

 

  1. 跨文档通信 API:window.postMessage()

调用postMessage方法实现父窗口http://test1.com向子窗口http://test2.com 发消息(子窗口同样可以通过该方法发送消息给父窗口)它可用于解决以下方面的问题:

 页面和其打开的新窗口的数据传递

 多窗口之间消息传递

 页面与嵌套的 iframe 消息传递

 上面三个场景的跨域数据传递

//父窗口打开一个子窗口

var openWindow = window.open('http://test2.com', 'title');

//父窗口向子窗口发消息(第一个参数代表发送的内容,第二个参数代表接收消息窗口的url)
openWindow.postMessage('Nice to meet you!', 'http://test2.com');

调用 message 事件,监听对方发送的消息

window.addEventListener('message', function(e) 
{ console.log(e.source); //发送消息的窗口
console.log(e.origin); //消息发向的网址
console.log(e.data); //发送的消息 }, false);
  1. JSONP

JSONP 是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性

好(兼容低版本 IE),缺点是只支持 get 请求,不支持 post 请求。

核心思想:网页通过添加一个<script>元素,向服务器请求 JSON 数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。

①原生实现:

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

② jQuery ajax:

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

③ Vue.js:

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

 4.    CORS

      CORS 是跨域资源分享(Cross-Origin Resource Sharing)的缩写。它是 W3C 标

准,属于跨源 AJAX 请求的根本解决方法。

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

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

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

①原生 ajax:

var xhr = new XMLHttpRequest();
//前端设置是否带cookie
xhr.withCredentials = true;
xhr.open('psot', '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 :

$.ajax({
url: 'http://www.test.com:8080/login',
type: 'get', data: {},
xhrFields: {
withCredentials: true
},
crossDomain: true
})

③vue-resource:

Vue.http.options.credentials = true;

④ axios :

axios.defaults.withCredentials = true;
原文地址:https://www.cnblogs.com/qingfengyuan/p/12980521.html