手把手带你实践4种前端跨域方式(附源码)
本文最后更新于:8 个月前
四种常用跨域方式:Vite配置代理跨域、手动配置CORS、使用cors库、Nginx配置代理
手把手带你实践4种前端跨域方式(附源码)
一、实验环境
前端项目:使用Vite创建一个Vue项目
后端项目:使用Express搭建一个web服务器
硬件:本地计算机(需要安装node.js环境,且需要符合vite对node的版本需求) + 阿里云轻量服务器(非必须)
二、准备工作
分别使用Vite
和Express
创建前端、后端项目。具体过程不展开赘述,直接放源码:
Qiuzcc/CORS_expriment: 用于探究前后端常用跨域方式的demo(github.com)
(大家可以clone下来直接用,具体的使用方法已经在代码注释和readme中进行了详细说明)
三、实验内容
1. 实验一:不进行任何配置
先后启动后端、前端项目,打开浏览器,查看控制台,观察到:XHR请求被CORS策略阻拦了
解析:
网页的源为:
http://localhost:5173:
,服务器的源为:http://localhost:3000
,两者都端口不一致,导致不同源从后端的access监听日志看,服务器已经做出了响应,并且实际上将Get请求的响应发回给了浏览器(如下图)。而 POST 和 PUT 请求则先发送了 OPTIONS 预检请求,在没有收到服务端返回的 CORS 同意字段之后,浏览器拒绝发送 POST 和 PUT 请求。
(「简单请求」直接发送实际请求,「非简单请求」先发送预检请求,再根据预检结果决定是否发送实际请求。更多详细内容,请阅读:一文说清CORS - timegogo )
从浏览器的「开发者工具」-「网络」中可以看到,“无法加载响应数据”,所以实际上是浏览器拒绝了解析响应(如下图一),POST 和 PUT 请求 没有发送出去(如下图二)
2. 实验二:在vite开发模式下配置代理跨域
配置参考链接:开发服务器选项 | Vite 官方中文文档 (vitejs.dev)
在vite.config,js
中配置server.proxy
,如下:
需要注意的是:这时在发送XHR请求时,url也需要相应地改变
查看【网络请求】,GET, POST, PUT三个请求都成功发送了,但是可以看到请求的 url 并不是服务端的地址,而是http://localhost:5173/api/
。所以,实际上,AxiosInstance 是向 dev server 发送的请求
原理解析:
这种方式能够解决跨域问题的原理是:
AxiosInstance
将请求发送给dev server
,dev server
再向真正的target
发送请求,因为dev server
不是浏览器,所以不受同源策略限制dev server
获得来自target
的响应后,返回给AxiosInstance
,因为dev server
和instance
是同源的,所以可以被解析
注意:
- 这种方式只能在开发模式下使用!
(因为生产环境下已经没有dev server这个东西了)
使用Tips:
可以通过 Axios 的 baseUrl 统一设置代理路径头,比如上面的
/api
,这样切换到生产环境时,可以快速切换url1
2
3
4
5
6
7
8
9
10
11
12
13
14// env.development
BASE_URL = '/api'
//env.production
BASE_URL = 'http://127.0.0.1:3000'
// .js文件
const instance = axios.create({
baseUrl: import.meta.env.BASE_URL
})
instance.get('/data').then().catch()
// 开发环境下为/api/data,然后通过dev server代理转发
// 生产环境下为http://127.0.0.1:3000/data
3. 实验三:后端手动配置CORS
CORS,全称是“跨域资源共享”(Cross-origin resource sharing)。是一个W3C标准。它新增了一组HTTP标头字段,来允许服务器声明哪些源站通过浏览器有权限访问哪些资源。
第一步,在后端配置CORS
第二步,前端正常发送XHR请求即可
查看【网络请求】
- GET请求获得了CORS同意字段(
Access-Control-Allow-Origin
等) - PUT和GET 都先发送了 OPTIONS 预检请求,收到CORS同意字段后,发送了实际的PUT和POST请求
原理解析:
首先,浏览器能够自动识别请求是否同源。然后,对于非同源请求,浏览器根据服务端返回的响应头相关字段(Access-Control-Allow-Origin
等)决定是否同意该跨域请求正常进行。例如:比对Access-Control-Allow-Origin
字段与请求的Origin
字段是否相同(相同则加载响应,不相同则阻止加载)
使用Tips:动态允许多个源
1 |
|
4. 实验四:使用cors库实现跨域
第一步,在后端安装cors - npm (npmjs.com)
1 |
|
第二步,在后端进行配置
第三步,在前端正常发送请求即可
结果与【实验三:后端手动配置CORS】一致
原理解析:
与实验三手动配置CORS原理相同,只是在这里 cors 库 把CORS的配置 集成封装起来了。相比起手动配置CORS,使用这种方式更加简单高效,而且不容易出现错误,推荐使用。
5. 实验五:配置代理服务器
在生产环境下,不存在dev server,但是可以通过Nginx、Apache等作为代理服务器。
接下来的操作,需要将代码打包上传到云服务器。