关于前端跨域

50 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 20 天,点击查看活动详情

跨域问题是前端在进行数据传递、接口请求等操作时会遇到的问题。那么到底什么是跨域,又该如何解决呢?

同源策略

首先,跨域与浏览器的同源策略有关,同源策略是浏览器的一种安全策略。由于同源策略的限制,只要协议、域名、端口有任何一个不同,都会被认为是不同的域,浏览器就会进行拦截,在请求数据时,不能执行其他网站的脚本。

如果缺少了同源策略,浏览器很容易受到 XSS、CSRF(跨站请求伪造)等攻击。

什么是跨域

跨域即是通过某些方式避开浏览器的安全限制。

同源策略限制的内容:

  • Cookie、LocalStorage、IndexedDB 等存储性内容
  • DOM 节点
  • AJAX 请求

允许跨域加载的内容:

  • img 标签
  • link 标签
  • script 标签

跨域的方法

1、JSONP

调用接口时,Ajax 无法进行跨域请求,而 script 标签的 src 属性中的链接可以访问跨域的 js 脚本。JSONP 就是利用这个特性,服务端不再返回 JSON 格式的数据,而是返回一段调用某个函数的 js 代码,在 src 中进行调用,从而实现跨域。

实现方式:动态创建 script 标签,再请求一个带参数的网址实现跨域通信。

JSONP 操作简单,兼容性好,但也有缺点:

  • 仅支持get方法
  • 不安全(可能会遭受 XSS 攻击)

2、iframe 相关

  • document.domain + iframe 跨域 两个访问的页面都通过 js 强制设置 document.domain (基础主域),从而实现同域。

  • location.hash + iframe 跨域 两个页面之间进行通信,通过中间页来实现。三个页面中,不同域之间的页面利用 iframe 的 location.hash 传值,相同域之间的页面使用 js 传递数据。

  • window.name + iframe 跨域 由 iframe 的 window.name 从外域传递到本地域(安全,避开了浏览器的访问限制)

3、CORS

在服务端设置 Access-Control-Allow-Origin 来配置可访问的域名,前端不需要进行设置。 如果要带 cookie 请求,前后端都需要进行设置。

4、postMessage 跨域

postMessage 是 window 提供的一个属性。

page1 发送

let targetWindow = document.getElementById('myFrame').contentWindow;
// 或者 const targetWindow = window.open('http://localhost:8080/page1');
targetWindow.postMessage('发送了一条消息', 'http://localhost:8080')

page2 接收:

window.addEventListener('message',(e) => {
    console.log(e.data, e.origin);
})

5、Node中间件

服务器向服务器请求不需要遵循同源策略。

除此之外,vue 可以引入 vue-jsonp 或者配置 Proxy 来解决跨域。