网络-跨域解决
最佳答案 问答题库658位专家为你答疑解惑
文章目录
- 前言
- 一、跨域是什么?
- 二、跨域的解决
- 1.JSONP
- 2.前端代理dev环境
- 3.后端设置请求头CORS
- 4.运维nginx代理
- 总结
前言
本文主要介绍跨域问题介绍并提供了四种解决办法。
一、跨域是什么?
准确的来说是浏览器存在跨域问题,浏览器为了安全考虑,也就是同源策略的限制,会拒绝跨域请求。
在这里同源策略是指:请求时拥有相同的协议、域名、端口,其中只要有一项不满足就被视为跨域。
跨域产生:
前端,这里直接请求,就会产生跨域问题
fetch('http://localhost:3000/api/json').then(res=>res.json()).then(res=>{console.log(res)})
后端,这里不做处理直接返回数据
app.get('/api/json',(req,res)=>{res.send({name:'smz'})
})
这里浏览器报错,是因为端口不一致导致跨域
这里值得注意的是,在发送跨域请求时,浏览器会先发送一个OPTIONS
请求(预检请求),用来获取服务器对跨域的支持情况。以下几种跨域请求都会触发预检请求,如果服务端在请求头中返回了适当的跨域头,则允许发送实际请求,否则拒绝。而其他简单请求则会正常发送。
- 使用了非简单请求
简单请求包括:GET
、HEAD
、POST
。
请求头部只包含以下字段:Accept
、Accept-Language
、Content-Language
、Content-Type
(仅限于application/x-www-form-urlencoded
、multipart/form-data
、text/plain
)。 - 自定义请求头部:跨域请求中的请求头部包含了自定义的字段
二、跨域的解决
1.JSONP
这种方式需要前后端一起协商解决,原理就是动态创建script标签,因为script标签src属性不受跨域限制。但是script标签只能发送get请求,是不安全的。
后端返回的是一个函数 这个函数前端需先定义好 他会把返回的值注入到这个函数的参数中,其中具有代表性的就是百度搜索跨域请求就是jsonp实现的。
前端:
<script>let text = document.querySelector('#text')// 动态创建script标签,添加scr请求地址拼接函数名称const jsonp = (name) =>{let script = document.createElement('script')script.src = 'http://localhost:3000/api/jsonp?callback=' + namedocument.body.appendChild(script)return new Promise((resolve)=>{window[name] = (data) =>{resolve(data)}})}// 利用函数接收返回的参数jsonp(`callback${new Date().getTime()}`).then(res=>{text.textContent = resconsole.log(res)})
</script>
后端:这里用Node
const express = require('express')
const app = express()
app.get('/api/jsonp',(req,res)=>{const {callback} = req.query // 函数名res.send(`${callback}('hello jsonp')`) //返回并将数据充当函数参数返回
})app.listen(3000,()=>{console.log('server is running')
})
跨域问题可以通过以下几种方式解决:
-
JSONP(JSON with Padding):通过动态创建
需要注意的是,跨域问题只存在于浏览器中,对于服务器端来说并不存在跨域问题。因此,以上解决方案都是在浏览器端实现的。
2.前端代理dev环境
利用vite或者webpack通过代理,将请求转发到对应的服务器上。
vite或者webpack配置文件,这里用vite
import {defineConfig} from 'vite'export default defineConfig({server:{proxy:{'/api':{target:'http://localhost:3000',changeOrigin:true,// 开启跨域}}}
})
请求:
fetch('/api/json').then(res=>res.json()).then(res=>{console.log(res)})
这里浏览器显示的是前端端口发送的请求,实际上已经通过请求转发给3000端口了,是vite开启了一个Node服务,在Node服务这里做了请求转发的操作。
只在开发环境生效,项目上线得用nginx
3.后端设置请求头CORS
后端设置跨域很简单,只要在返回请求头中带入允许跨域的接口地址就行Access-Control-Allow-Origin
将其值设置为*可以放行全部,但是不建议这样放行全部,可以指定ip。在这里要注意一下非简单请求是会发一个预检请求的,这个预检请求需要放行带上响应头返回。保证请求能够跨域。
预检(options)请求放行返回,这里使用后端是node
app.options('/api/*', (req,res) => {res.setHeader("Access-Control-Allow-Origin","*")res.setHeader("Access-Control-Allow-Headers", "*");res.end()
})
其他请求带响应头
res.setHeader('Access-Control-Allow-Origin','*')
其实在产生跨域问题时,浏览器就提示我们这样的做法了
4.运维nginx代理
在项目上线时,通过nginx代理进行请求转发。
在nginx配置文件nginx.conf中加入代理配置
location /api {proxy_pass http://127.0.0.1:5000;}
总结
本文记录了,跨域问题在前后端的解决方法,以及不同环境下的解决方案。
99%的人还看了
相似问题
- 前后端分离项目跨域请求的问题与解决办法
- Springboot和Vue+MYSQL项目(基本介绍+前后端结合初步项目)+maven+mybatis
- ssm+vue的药店药品信息管理系统(有报告)。Javaee项目,ssm vue前后端分离项目。
- 后端-锁专题:synchronized(java对象结构、锁的类型、锁升级流程...)
- 微信小程序开发-----发起网络请求携带后端token
- django理解02 前后端分离中的问题
- 04 后端增删改查【小白入门SpringBoot + Vue3】
- 准备后端接口服务环境
- SpirngBoot + Vue 前后端分离开发工具代码
- SpringBoot 2.x 实战仿B站高性能后端项目
猜你感兴趣
版权申明
本文"网络-跨域解决":http://eshow365.cn/6-16852-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!
- 上一篇: python多线程与多进程
- 下一篇: Electron.js入门-构建第一个聊天应用程序