跨域和同源详解

203 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

跨域

同源策略

  • 开发过程中主要遇到的同源问题,主要是比较两个url是否同源。

判断条件

  1. 协议是否相同(http、https、file)
  2. 主机地址是否相同(www.xxx.com 127.0.0.1)
  3. 端口(0~65535)http默认的电动车需按扣是80(可以不写),https默认端口是443 , MySQL默认的端口是3306

如果两个url协议、主机地址、端口都相同,那么这两个url是同源,否则就是非同源

非同源受到限制:

  • Cookie无法操作
  • DOM无法操作
  • Ajax请求无效(请求可以发送,服务器也会处理这次请求,但是响应结果会被浏览器拦截)

违反了同源策略的请求,叫做跨域请求

跨域解决

  1. 解决的方法有很多种,和大家讲下主流的两种把:分别是JSONP和CPRS

CPRS方案

CPRS:通过服务器设置响应头来实现跨域,比较符合解决跨域的真正问题

JSONP

JSONP:

  1. JSONP方案只支持GET请求
  2. JSONP方案和AJAX没有任何关系
  3. JSONP任何浏览器都支持,兼容性好

原理:

  • 客户端利用 script 标签的 src 属性,去请求一个接口,因为src属性不受跨域影响。
  • 服务端响应一个字符串
  • 客户端接收到字符串,然后把它当做JS代码运行。

后端接口代码:

 app.get('/api/jsonp', (req, res) => {
   // res.send('hello');
   // res.send('console.log(1234)');
   // res.send('abc()')
   // res.send('abc(12345)')
 ​
   // 接收客户端的函数名
   let fn = req.query.callback;
   let obj = { status: 0, message: '登录成功' };
   let str = JSON.stringify(obj);
   res.send(fn + `(${str})`);
 });

前端代码:

 <script>
   // 提前准备好一个函数
   function xxx(res) {
     console.log(res)
   }
 ​
 </script>
 ​
 <script src="http://localhost:3006/api/jsonp?callback=xxx"></script>
  • 前端需要做什么?

    • 如果使用jQuery,$.ajax({ dataType: 'jsonp' }),必须指定dataType选项为jsonp即可
  • 后端需要做什么?

    • 如果使用express,那么直接调用 res.jsonp(数据) 即可。