vue+springboot跨域问题(解决SpringBoot和前端Vue的跨域问题)
一 、为什么会出现跨域问题
出于浏览器的同源策略限制 。同源策略(Sameoriginpolicy)是一种约定 ,它是浏览器最核心也最基本的安全功能 ,如果缺少了同源策略 ,则浏览器的正常功能可能都会受到影响 。可以说Web是构建在同源策略基础之上的 ,浏览器只是针对同源策略的一种实现 。同源策略会阻止一个域的 。javascript脚本和另外一个域的内容进行交互 。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol) ,主机(host)和端口号(port) 。
二 、什么是跨域?
要了解什么是跨域 ,我们先说一下同源的概念 。同源 ,是指协议 、域名 、端口都相同 。
例如:http://192.168.0.1:8080与https://192.168.3.1:8080不是同源 ,因为协议不同 ,第一个冒号前面的为协议 ,中间的为域名 ,第二个冒号后面的为端口 ,只要满足有一处不同,则就不是同源 。
所谓跨域就是从 A 向 B 发请求 ,如若他们的地址协议 、域名 、端口都不相同 ,直接访问就会造成跨域问题,跨域是非常常见的现象!请求是跨域的但并不一定会报错 ,普通的图片请求 。css文件请求是不会报错的 。报错的条件是浏览器的同源策略 ,且发送Ajax请求 ,跨域是客户端问题 。
类似于如下:
三 、常见的跨域场景
四 、如何解决跨域?
1.JSONP jsonp的原理就是利用<script>标签没有跨域限制 ,通过<script>标签src属性 ,发送带有callback参数的GET请求 ,服务端将接口返回数据拼凑到callback函数中 ,返回给浏览器 ,浏览器解析执行 ,从而前端拿到callback函数返回的数据。
jsonp的缺点:只能发送get一种请求 。
2.CORS
CORS
是一个W3C标准 ,全称是"跨域资源共享"(Cross-origin resource sharing) 。
它允许浏览器向跨源服务器 ,发出XMLHttpRequest请求 ,从而克服了AJAX只能同源使用的限制。
CORS需要浏览器和服务器同时支持 。目前,所有浏览器都支持该功能 ,IE浏览器不能低于IE10 。
浏览器将CORS跨域请求分为简单请求和非简单请求 。
只要同时满足一下两个条件 ,就属于简单请求
(1)使用下列方法之一: head get post(2)请求的Heder是
Accept Accept-Language Content-Language Content-Type: 只限于三个值:application/x-www-form-urlencoded 、multipart/form-data 、text/plain不同时满足上面的两个条件,就属于非简单请求 。浏览器对这两种的处理 ,是不一样的 。
3.nginx反向代理接口跨域 可以将前端项目部署到和接口同源的当前本地的服务器上 。在vue.config.js 中进行代理配置 ,假设当我访问 http://localhost:9528/api/login 时会转换为间接访问 http://localhost:3000/api/login
devServer: { // 其他代码省略 。 。 。 。 。 // 代理配置 proxy: { // 代理服务器 ,当请求的网址是http://localhost:3000的时候 ,会转成http://192.168.80.115:3000 // /api 是 看接口文档所写的 ,每当访问本地的/api接口时 ,会转化为访问真实的服务器 /api: { target: http://localhost:3000 // 我们要代理的真实接口地址 } }4.web sockets 它是一种浏览器的API ,它的目标是在一个单独的持久连接上提供全双工 、双向通信 。(同源策略对web sockets不适用)web sockets原理:在JS创建了web socket之后 ,会有一个HTTP请求发送到浏览器以发起连接。取得服务器响应后 ,建立的连接会使用HTTP升级从HTTP协议交换为web sockt协议 。 只有在支持web socket协议的服务器上才能正常工作 。
属性:
5.node.js中间件代理跨域
node中间件实现跨域代理 ,原理大致与nginx相同 ,都是通过启一个代理服务器 ,实现数据的转发,也可以通过设置cookieDomainRewrite参数修改响应头中cookie中域名 ,实现当前域的cookie写入 ,方便接口登录认证。
1)非vue框架的跨域 使用node + express + http-proxy-middleware搭建一个proxy服务器 。 前端代码: var xhr = new XMLHttpRequest(); // 前端开关:浏览器是否读写cookie xhr.withCredentials = true; // 访问http-proxy-middleware代理服务器 xhr.open(get, http://www.domain1.com:3000/login?user=admin, true); xhr.send(); 中间件服务器代码: var express = require(express); var proxy = require(http-proxy-middleware); var app = express(); app.use(/, proxy({ // 代理跨域目标接口 target: http://www.domain2.com:8080, changeOrigin: true, // 修改响应头信息,实现跨域并允许带cookie onProxyRes: function(proxyRes, req, res) { res.header(Access-Control-Allow-Origin, http://www.domain1.com); res.header(Access-Control-Allow-Credentials, true); }, // 修改响应信息中的cookie域名 cookieDomainRewrite: www.domain1.com // 可以为false ,表示不修改 })); app.listen(3000); console.log(Proxy server is listen at port 3000...);2)vue框架的跨域
node + vue + webpack + webpack-dev-server搭建的项目 ,跨域请求接口 ,直接修改webpack.config.js配置 。开发环境下 ,vue渲染服务和接口代理服务都是webpack-dev-server同一个 ,所以页面与代理接口之间不再跨域 。
webpack.config.js部分配置: module.exports = { entry: {}, module: {}, ... devServer: { historyApiFallback: true, proxy: [{ context: /login, target: http://www.domain2.com:8080, // 代理跨域目标接口 changeOrigin: true, secure: false, // 当代理某些https服务报错时用 cookieDomainRewrite: www.domain1.com // 可以为false ,表示不修改 }], noInfo: true } }五 、SpringBoot跨域问题的解决
在Springboot项目里加上这个配置文件CorsConfig.java ,重启之后即可实现跨域访问 ,前端无需再配置跨域 。
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; @Configuration public class CorsConfig { // 当前跨域请求最大有效时长 。这里默认1天 private static final long MAX_AGE = 24 * 60 * 60; @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址 corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头 corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法 corsConfiguration.setMaxAge(MAX_AGE); source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置 return new CorsFilter(source); } }六、前端跨域解决
request.js用来请求数据 ,封装的代码如下:
import axios from axios const request = axios.create({ baseURL: /api, // 注意!! 这里是全局统一加上了 /api 前缀 ,也就是说所有接口都会加上/api前缀在 ,页面里面写接口的时候就不要加 /api了 ,否则会出现2个/api,类似 /api/api/user这样的报错 ,切记!!! timeout: 5000 }) // request 拦截器 // 可以自请求发送前对请求做一些处理 // 比如统一加token ,对请求参数统一加密 request.interceptors.request.use(config => { config.headers[Content-Type] = application/json;charset=utf-8; // config.headers[token] = user.token; // 设置请求头 return config }, error => { return Promise.reject(error) }); // response 拦截器 // 可以在接口响应后统一处理结果 request.interceptors.response.use( response => { let res = response.data; // 如果是返回的文件 if (response.config.responseType === blob) { return res } // 兼容服务端返回的字符串数据 if (typeof res === string) { res = res ? JSON.parse(res) : res } return res; }, error => { console.log(err + error) // for debug return Promise.reject(error) } ) export default requestvue.config.js:
// 跨域配置 module.exports = { devServer: { //记住,别写错了devServer//设置本地默认端口 选填 port: 9876, proxy: { //设置代理 ,必须填 /api: { //设置拦截器 拦截器格式 斜杠+拦截器名字 ,名字可以自己定 target: http://localhost:9999, //代理的目标地址 changeOrigin: true, //是否设置同源 ,输入是的 pathRewrite: { //路径重写 ^/api: //选择忽略拦截器里面的内容 } } } } }七 、前后端都跨域
如果后端设置了跨域配置 ,则使用下面的request.js 代码:
import axios from axios const request = axios.create({ baseURL: http://localhost:9090, // 注意!! 这里是全局统一加上了 后端接口前缀 前缀 ,后端必须进行跨域配置! timeout: 5000 }) // request 拦截器 // 可以自请求发送前对请求做一些处理 // 比如统一加token ,对请求参数统一加密 request.interceptors.request.use(config => { config.headers[Content-Type] = application/json;charset=utf-8; // config.headers[token] = user.token; // 设置请求头 return config }, error => { return Promise.reject(error) }); // response 拦截器 // 可以在接口响应后统一处理结果 request.interceptors.response.use( response => { let res = response.data; // 如果是返回的文件 if (response.config.responseType === blob) { return res } // 兼容服务端返回的字符串数据 if (typeof res === string) { res = res ? JSON.parse(res) : res } return res; }, error => { console.log(err + error) // for debug return Promise.reject(error) } ) export default request⛵小结
以上就是对解决SpringBoot和前端Vue的跨域问题简单的概述 ,现在我们的项目就更加的趋于完美了 ,也提升了我们对于编程的能力和思维!
如果这篇文章有帮助到你 ,希望可以给作者点个赞👍 ,创作不易 ,如果有对后端技术 、前端领域感兴趣的 ,也欢迎关注 ,我将会给你带来巨大的收获与惊喜💝💝💝!
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!