前端跨域方案整理
vite配置proxy跨域
在 vue3 项目中,找到 vite.config.ts 文件,在其中进行 vite 的相关配置.下面展示 选项 写法(可解决跨域问题)
server: {
port: 8080,
proxy: {
"/api": {
target: "http://localhost:7001", // 所要代理的目标地址
changeOrigin: true, //允许跨域
ws: true, // 开启 websockets 代理
secure: false, // 验证 SSL 证书
rewrite: (path) => path.replace(/^\/api/, ""), // 重写传过来的path路径
},
},
},
简要说明
前端跨域问题其实是一个安全问题,就是为了防止不同域名的服务之间进行互相访问,以避免恶意程序对后端资源进行非法获取。在开发的时候,我们就可以利用代理来把请求进行代理,把域名等改成一样的,这样就避免了跨越的问题。
上面配置的 后端地址为 http://localhost:7001 ,代理以 /api 开头的所有 API 请求,并把它转发到http://localhost:7001
例如: 前端请求地址一般为简写 /api/user,前端实际请求地址为 http://localhost:7001/api/user
实际转发到后端的地址是省略了 /api 的,为 http://localhost:7001/user
同时,也可以代理多个地址,例如
server: {
proxy: {
"/api": {
target: "http://localhost:7001",
changeOrigin: true,
},
"foo": {
target: "http://localhost:7002",
changeOrigin: true,
}
},
},
注意*****
配置 vite.config.ts 后,记得重启项目,否则不会生效
最经典的跨域方案jsonp
jsonp本质上是⼀个Hack,它利⽤ <script> 标签不受同源策略限制的特性进⾏跨域操作。
jsonp优点:
- 实现简单
- 兼容性非常好
jsonp的缺点:
- 只支持get请求(因为 <script> 标签只能get)
- 有安全性问题,容易遭受xss攻击
- 需要服务端配合jsonp进行一定程度的改造
jsonp的实现:
function JSONP({ url, params, callbackKey, callback }) { // 在参数⾥制定 callback 的名字 params = params || {} params[callbackKey] = 'jsonpCallback' // 预留 callback window.jsonpCallback = callback // 拼接参数字符串 const paramKeys = Object.keys(params) const paramString = paramKeys .map(key => `${key}=${params[key]}`) .join('&') // 插⼊ DOM 元素 const script = document.createElement('script') script.setAttribute('src', `${url}?${paramString}`) document.body.appendChild(script) } JSONP({ url: 'http://s.weibo.com/ajax/jsonp/suggestion', params: {key: 'test', }, callbackKey: '_cb', callback(result) { console.log(result.data) } })
最流行的跨域方案cors
cors是目前主流的跨域解决⽅案,跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一
个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服
务器不同的域、协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。
如果你用express,可以这样在后端设置
//CORS middleware var allowCrossDomain = function(req, res, next) { res.header('Access-Control-Allow-Origin', 'http://example.com'); res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); res.header('Access-Control-Allow-Headers', 'Content-Type'); next(); } //... app.configure(function() { app.use(express.bodyParser()); app.use(express.cookieParser()); app.use(express.session({ secret: 'cool beans' })); app.use(express.methodOverride()); app.use(allowCrossDomain); app.use(app.router); app.use(express.static(__dirname + '/public')); });
在生产环境中建议用成熟的开源中间件解决问题。
最方便的跨域方案Nginx
用nginx解决前端跨域问题
https://blog.csdn.net/enhenglhm/article/details/123791603
axious中文文档
https://zhuanlan.zhihu.com/p/414706826
nginx是一款极其强大的web服务器,其优点就是轻量级、启动快、高并发。
现在的新项目中nginx几乎是首选,我们用node或者java开发的服务通常都需要经过nginx的反向代理。
反向代理的原理很简单,即所有客户端的请求都必须先经过nginx的处理,nginx作为代理服务器再讲请求转发给node或
者java服务,这样就规避了同源策略。
#进程, 可更具cpu数量调整 worker_processes 1; events { #连接数 worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; #连接超时时间,服务器会在这个时间过后关闭连接。 keepalive_timeout 10; # gizp压缩 gzip on; # 直接请求nginx也是会报跨域错误的这⾥设置允许跨域 # 如果代理地址已经允许跨域则不需要这些, 否则报错(虽然这样nginx跨域就没意义了) add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Headers X-Requested-With; add_header Access-Control-Allow-Methods GET,POST,OPTIONS; # srever模块配置是http模块中的⼀个⼦模块,⽤来定义⼀个虚拟访问主机 server { listen 80; server_name localhost; # 根路径指到index.html location / { root html; index index.html index.htm; } # localhost/api 的请求会被转发到192.168.0.103:8080 location /api { rewrite ^/b/(.*)$ /$1 break; # 去除本地接⼝/api前缀, 否则会出现404 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://192.168.0.103:8080; # 转发地址 } # 重定向错误⻚⾯到/50x.html error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
总之,虽然前端开发人员可以了解和使用Nginx服务器的相关配置信息,但通常情况下不会独立配置Nginx服务器。
在实际项目中,前端开发人员需要与服务器管理员协作,以确保服务器的配置和前端代码之间的协调和一致性。
其它跨域方案
1. HTML5 XMLHttpRequest 有一个API,postMessage()方法允许来自不同源的脚本采用异步方式进行有限的通信,
可以实现跨文本档、多窗口、跨域消息传递。
2. WebSocket 是一种双向通信协议,在建立连接之后,WebSocket 的 server 与 client 都能主动向对方发送或接收数
据,连接建立好了之后 client 与 server 之间的双向通信就与 HTTP 无关了,因此可以跨域。
3. window.name + iframe:window.name属性值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常
长的 name 值,我们可以利用这个特点进行跨域。
4. location.hash + iframe:a.html欲与c.html跨域相互通信,通过中间页b.html来实现。 三个页面,不同域之间利用
iframe的location.hash传值,相同域之间直接js访问来通信。
5. document.domain + iframe: 该方式只能用于二级域名相同的情况下,比如 a.test.com 和 b.test.com 适用于该方
式,我们只需要给页面添加 document.domain ='test.com' 表示二级域名都相同就可以实现跨域,两个页面都通过js
强制设置document.domain为基础主域,就实现了同域。
其余方案来自于九种跨域方式实现原理
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了