解决跨域问题的5种办法
前言
跨域问题一直是前后端交互过程中遇见频率最高的问题,本文带来五种解决跨域问题的办法,总有一种适合你。
跨域
什么是跨域?
- 同源:两个资源的 协议、域名、端口都相同。否则就是跨域
为什么要有跨域?
- 浏览器的安全限制,为了防止读取非同源的DOM、Cookie、LocalStorage、IndexDB;
跨域请求的过程?
- 向非同源发起请求,请求资源跨域时,浏览器一般会先发起预检请求,检测资源是否支持跨域,再发起真实请求,请求类型为
preflight
,请求方法为OPTIONS
表示预检请求。
解决跨域的五种方式
- 把协议、域名、端口改成相同的;
- 在响应头添加 Access-Control-Allow-Origin 相关字段来允许跨域,利用这种解决思路具体的实现的方式有 nginx配置、后端手动修改字段CORS、后端中间件请求拦截、谷歌插件等方式;
- JSONP,利用了script标签不受浏览器同源策略的影响;
- 反向代理,利用跨域只对浏览器有效,在node中开启跨域代理,负责请求转发。Vue和React都有代码配置,适用于开发环境;
- CSP(content-Security-policy)设置白名单。
下面来展开聊其中的几个具体实现
Nginx配置解决跨域问题
在nginx服务器中配置,为响应头添加跨域字段
location ^~ /api/ { |
JSONP解决跨域问题
JSONP利用了script标签不受浏览器同源策略的影响,可以通过src属性,请求非同源的js脚本。除了script标签,img、link标签也支持跨域。但是img只能跨域图片(其实也可以获取图片二进制再使用JS解析也能拿到数据,但没必要怎么做)、link只能跨域css。
JSONP的4大缺陷:
- 只支持get请求
- 不安全
- 有缓存
- 传递信息有限制
JSONP伪代码
其实就是本地定义一个函数,用发起请求(发起的JS脚本请求)的方式调用自己
前端HTML的代码
<script> |
同级目录JS文件夹下的getdata.js
文件
abc({ name: 'ls', age: 30 }) //回调了HTML中的abc函数 |
实现JSONP
前端部分
|
Node后端部分
const http = require('http') |
jQuery发起JSONP请求
jQuery是通过动态创建和移除script标签的方式来发起JSONP请求。在发起SONP请求的时候,动态向<header>
中append一个<script>
标签;在JSONP请求成功以后,动态从<header>
中移除刚才append进去的<script>
标签。
// 发起JSONP的请求 |
CSP配置解决跨域问题
CSP的作用:
防XSS等攻击的利器。CSP 的实质就是白名单制度,开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单。它的实现和执行全部由浏览器完成,开发者只需提供配置。CSP 大大增强了网页的安全性。攻击者即使发现了漏洞,也没法注入脚本,除非还控制了一台列入了白名单的可信主机。开发者明确告诉客户端(制定比较严格的策略和规则),哪些外部资源是可以加载和执行的 ,即使攻击者发现漏洞,但是它是没办法注入脚本的
两种方式实现CSP:
- 可以在HTTP响应头添加CSP字段并配置策略
- 可以在HTML标签中添加
<meta http-equiv="Content-Security-Policy"content="default-src 'self'; img-src https://freepngimg.com/ " />
总结
本文详细阐述了跨域问题的原因和五种解决方案;
- 把协议、域名、端口改成相同的
- 在响应头添加 Access-Control-Allow-Origin 相关字段来允许跨域
- JSONP
- 反向代理
- CSP
并针对几个常用的跨域方案展开介绍
感谢小伙伴们的耐心观看,本文为笔者个人学习记录,如有谬误,还请告知,万分感谢!如果本文对你有所帮助,还请点个关注点个赞~,您的支持是笔者不断更新的动力!