放肆青春的博客
首页
前端
算法
网络
面试
技术
后端
运维
杂项
数据库
工具
网址
电脑
个人
文章
  • 分类
  • 标签
  • 归档
github (opens new window)
gitee (opens new window)

放肆青春

一个前端菜鸟的技术成长之路
首页
前端
算法
网络
面试
技术
后端
运维
杂项
数据库
工具
网址
电脑
个人
文章
  • 分类
  • 标签
  • 归档
github (opens new window)
gitee (opens new window)
  • 计算机网络
  • http
  • https
  • 缓存
  • TCP
  • UDP
  • DNS
  • CDN
  • 跨域
    • 同源策略
      • 同源策略的限制
    • 跨域
      • jsonp 跨域
      • 跨域资源共享(CORS)
      • nginx 代理跨域
      • nodejs 中间件代理跨域
      • postMessage 跨域
      • WebSocket 协议跨域
      • document.domain + iframe 跨域
  • 请求

    • ajax
    • axios
    • fetch
    • websocket
  • 前端本地存储
  • 代理
  • 加密
  • 从输入URL到页面加载的过程
  • network
放肆青春
2021-03-17

跨域

# 同源策略

同源:协议、域名、端口相同

# 同源策略的限制

同源策略限制以下几种行为:

  1. Cookie、LocalStorage 和 IndexDB 无法读取

  2. DOM 和 Js 对象无法获得

  3. AJAX 请求不能发送

# 跨域

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

跨域的解决办法:

  1. 通过 jsonp 跨域

  2. 跨域资源共享(CORS)

  3. nginx 代理跨域

  4. nodejs 中间件代理跨域

  5. postMessage 跨域

  6. WebSocket 协议跨域

# jsonp 跨域

script 标签的 src,img 标签的 src,link 标签的 href 没有被同源策略所限制

原理:动态创建一个<script>标签,而 script 标签的 src 属性是没有跨域的限制的。,src 中放入链接和回调方法。

优点:兼容性好

缺点:

  1. 只支持 get 请求,不支持 post 请求。

  2. 安全性不高

  3. jsonp 在调用失败的时候不会返回各种 HTTP 状态码。

jsonp 安全性防范:

1、防止 callback 参数意外截断 js 代码,特殊字符单引号双引号,换行符均存在风险(方案:作严整的格式检查,或强制约定指定格式)

2、防止 callback 参数恶意添加标签(如 script),造成 XSS 漏洞(方案:过滤特殊字符)

3、防止跨域请求滥用,阻止非法站点恶意调用(方案:refer 白名单匹配,以及 cookieToken 机制来限制)

代码实现:

<button id="btn">点击</button>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script>
  $("#btn").click(function() {
    var frame = document.createElement("script");
    frame.src =
      "http://localhost:3000/article-list?name=leo&age=30&callback=func";
    $("body").append(frame);
  });

  function func(res) {
    alert(res.message + res.name + "你已经" + res.age + "岁了");
  }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 跨域资源共享(CORS)

普通跨域请求:只服务端设置 Access-Control-Allow-Origin 即可,前端无须设置

若要带 cookie 请求:前后端都需要设置。

前端设置

  1. ajax 设置:xhr.withCredentials = true; // 跨域请求是否提供凭据信息(cookie、HTTP认证及客户端SSL证明等)

  2. axios 设置:axios.defaults.withCredentials = true

服务器端设置:

允许前端带认证 cookie:启用此项后,上面的域名不能为'*',必须指定具体的域名

Access-Control-Allow-Credentials: true

允许跨域访问的域名:若有端口需写全(协议+域名+端口),若没有端口末尾不用加'/'

Access-Control-Allow-Origin: http://www.domain1.com

# nginx 代理跨域

跨域原理: 同源策略是浏览器的安全策略,不是 HTTP 协议的一部分。服务器端调用 HTTP 接口只是使用 HTTP 协议,不会执行 JS 脚本,不需要同源策略,也就不存在跨越问题

实现思路:通过 nginx 配置一个代理服务器(域名与 domain1 相同,端口不同)做跳板机,反向代理访问 domain2 接口,并且可以顺便修改 cookie 中 domain 信息,方便当前域 cookie 写入,实现跨域登录。

  1. 可在 nginx 的静态资源服务器中加入以下配置
location / {
  add_header Access-Control-Allow-Origin *;
}
1
2
3

# nodejs 中间件代理跨域

原理大致与 nginx 相同,都是通过启一个代理服务器,实现数据的转发,也可以通过设置 cookieDomainRewrite 参数修改响应头中 cookie 中域名,实现当前域的 cookie 写入,方便接口登录认证。

非 vue 框架的跨域(2 次跨域):

利用 node + express + http-proxy-middleware 搭建一个 proxy 服务器。

vue 框架的跨域(1 次跨域):

利用 node + webpack + webpack-dev-server 代理接口跨域。在开发环境下,由于 vue 渲染服务和接口代理服务都是 webpack-dev-server 同一个,所以页面与代理接口之间不再跨域,无须设置 headers 跨域信息了。

# postMessage 跨域

postMessage 是 HTML5 中的 API,且是可以跨域操作的 window 属性

作用:

  1. 页面和其打开的新窗口的数据传递
  2. 多窗口之间消息传递
  3. 页面与嵌套的 iframe 消息传递
  4. 上面三个场景的跨域数据传递

语法:postMessage(data,origin)

  1. data: html5 规范支持任意基本类型或可复制的对象,但部分浏览器只支持字符串,所以传参时最好用 JSON.stringify()序列化。

  2. origin: 协议+主机+端口号,也可以设置为"*",表示可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。

# WebSocket 协议跨域

WebSocket protocol 是 HTML5 一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯,是 server push 技术的一种很好的实现。

# document.domain + iframe 跨域

此方案仅限主域相同,子域不同的跨域应用场景。

实现原理:两个页面都通过 js 强制设置 document.domain 为基础主域,就实现了同域。

更新时间: 12/21/2021, 3:54:38 PM
CDN
ajax

← CDN ajax→

最近更新
01
前端权限管理
02-24
02
vue2指令
02-24
03
vue2 hook
02-24
更多文章>
Theme by Vdoing | Copyright © 2019-2022 放肆青春
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式