开启掘金成长之旅!这是我参与「掘金日新计划 · 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 来解决跨域。