注册

跨域问题及常见解决方法



1.出现跨域问题是因为浏览器的同源策列限制,下面是MDN文档对浏览器同源策略的描述,简单来说就是:

同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)

浏览器的同源策略

同源策略是一个重要的安全策略,它用于限制一个origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。

同源的定义

如果两个 URL 的 protocol、port (en-US) (如果有指定的话)和 host 都相同的话,则这两个 URL 是同源。这个方案也被称为“协议/主机/端口元组”,或者直接是 “元组”。(“元组” 是指一组项目构成的整体,双重/三重/四重/五重/等的通用形式)。

2.四种常见解决跨域的方法:

一,CORS:

跨域资源共享,它允许浏览器向非同源服务器,发出XMLHttpRequest请求。它对一般请求和非一般请求的处理方式不同: 1、一般跨域请求(对服务器没有要求):只需服务器端设置Access-Control-Allow-Origin 2、非一般跨域请求(比如要请求时要携带cookie):前后端都需要设置。

一般跨域请求服务器设置代码: (1)Node.JS

const http = require('http');
const server = http.createServer();
const qs = require('querystring');

server.on('request', function(req, res) {
   var postData = '';
   // 数据块接收中
   req.addListener('data', function(chunk) {
       postData += chunk;
  });
   // 数据接收完毕
   req.addListener('end', function() {
       postData = qs.parse(postData);
       // 跨域后台设置
       res.writeHead(200, {
           'Access-Control-Allow-Credentials': 'true',     // 后端允许发送Cookie
           'Access-Control-Allow-Origin': 'http://www.example.com',    // 允许访问的域(协议+域名+端口)  
      });
       res.end(JSON.stringify(postData));
  });
});
server.listen('8080');
console.log('running at port 8080...');

复制代码

(2)PHP

<?php
header("Access-Control-Allow-Origin:*");
复制代码

如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie。

前端请求携带cookie代码:

(1)原生JavaScript

const xhr = new XMLHttpRequest(); 
// 前端设置是否带cookie
xhr.withCredentials = true;
};
复制代码

(2)axios

axios.defaults.withCredentials = true
复制代码

二,JSONP

JSONP 只支持get请求,不支持post请求。 核心思想:网页通过添加一个<scriot>标签,向服务器请求 JSON 数据,服务器收到请求后,将数据放在一个指定名字的回调函数的参数位置传回来。

原生JavaScript代码:

<script src="http://example.php?callback=getData"></script>
// 向服务器发出请求,请求参数callback是下面定义的函数名字

// 处理服务器返回回调函数的数据
<script type="text/javascript">
   function getData(res)
  {
       console.log(res.data)
  }
</script>
复制代码

三,设置document.domain

因为浏览器是通过document.domain属性来检查两个页面是否同源,因此只要通过设置相同的document.domain,两个页面就可以共享Cookie(此方案仅限主域相同,子域不同的跨域应用场景。)

// 两个页面都设置
document.domain = 'test.com';
复制代码

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

调用postMessage方法实现父窗口向子窗口发消息(子窗口同样可以通过该方法发送消息给父窗口)

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

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

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


作者:玩具大兵
来源:https://juejin.cn/post/7035562059152490526

0 个评论

要回复文章请先登录注册