目录
- 友情提醒
- 第一章、跨越问题解决
- 1.1)什么是跨域问题?
- 1.2)第一种解决方式:后端设置允许跨域访问
- 1.3)第二种解决方式:前端配置代理
- 第二章、配置代理服务器
- 2.1)配置简单代理服务器
- 2.2)多个代理配置
友情提醒
先看文章目录,大致了解知识点结构,直接点击文章目录可以跳转到文章指定位置。
第一章、跨越问题解决
1.1)什么是跨域问题?
vue单页应用项目开发时,避免不了要请求后端,这时通常就会出现跨域问题
浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都会导致跨域问题。即前端接口去调用不在同一个域内的后端服务器而产生的问题。
1.2)第一种解决方式:后端设置允许跨域访问
注意:但在生产环境下,为了安全起见,还是建议不要设置允许跨域访问,或者 限制允许跨域的IP
例如:SpringMVC允许跨域的设置
1.使用的方式用@Controller和@CrossOrgin一起使用,可以实现跨域!
只有Spring版本从4.2开始才有跨域支持!
//某个方法支持跨域访问:在方法上增加@CrossOrigin注解
@RequestMapping("/crossDomain2.action")
@ResponseBody
@CrossOrigin
public String crossDomain2(HttpServletRequest req, HttpServletResponse res, String name){
return null;
}
整个Controller都支持跨域访问
//整个Controller都支持跨域访问,在类上面加上注解@CrossOrigin
@Controller
@CrossOrigin
public class TestController {
}
2.使用定义全局的跨域配置:可以通过实现WebMvcConfigurer并重写 addCorsMappings方法来实现跨域
3.使用过滤器方式
public class HeaderFilter implements Filter{
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse) res;
String originHeader = request.getHeader("Origin");
response.setHeader("Access-Control-Allow-Origin", originHeader);
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "0");
response.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("XDomainRequestAllowed","1");
response.setHeader("XDomainRequestAllowed","1");
chain.doFilter(request, response);
}
}
1.3)第二种解决方式:前端配置代理
代理服务器的主要思想是通过建立一个端口号和前端相同的代理服务器进行中转,从而解决跨域问题。因为代理服务器与前端处于同一个域中,不会产生跨域问题;而且代理服务器与服务器之间的通信是后端之间的通信,不会产生跨域问题。
原理:浏览器和服务器当:协议、ip、端口号有一个不一致,就是违背同源策略
找一个和浏览器同源的服务器,让这个服务器帮我们代理给别的服务器发请求服务器之间不必遵守同源策略
第二章、配置代理服务器
vue-cli配置代理的两种方法:都要编写vue.config.js
2.1)配置简单代理服务器
①优点:配置简单,请求资源时直接发给前端(8080)即可
②缺点:不能配置多个代理,不能灵活的控制请求是否走代理
③工作方式:若按照上述配置代理,当请求了不存在的资源时,那么该请求就 会转发给服务器(有限匹配前端资源)
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,//对使用的JS 语法进行转译 不同版本使用不同
// 开启代理服务器,注意:这里的端口号写后端的端口号(方式一)
//简单代理服务器
devServer:{
port:8080,//当前前端服务器的端口号 不写默认是8080
proxy:"http://127.0.0.1:8081"//代理服务器
}
})
2.2)多个代理配置
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,//对使用的JS 语法进行转译 不同版本使用不同
// 开启代理服务器,注意:这里的端口号写后端的端口号(方式一)
/*//简单代理服务器
devServer:{
port:8080,//当前前端服务器的端口号 不写默认是8080
proxy:"http://127.0.0.1:8081"//代理服务器
}*/
/*配置多个代理*/
devServer:{
port:9527,//前端服务器端口号变成9527
proxy:{
//配置多个代理服务器格式:
/*"/代理服务器的名字":{
target:"代理服务器的地址",
ws:true,//用于支持websocket
changeOrigin: true,// 用于控制请求头中的host值 代理欺骗 可以不写
pathRewrite: {'^/代理服务器名字': ''} //重写路径,把所有路径中包含/代理服务器名的路径替换为空字符串
}*/
"/myFirstProxy":{
target:"http://127.0.0.1:8081", //代理服务器的地址
ws:true,//用于支持websocket
//就是把/myFirstProxy变成了空字符串
pathRewrite:{"^/myFirstProxy":""}//重写路径,把所有路径中包含/代理服务器名的路径替换为空字符串
},
"/mySecondProxy":{
target:"http://127.0.0.1:8082", //代理服务器的地址
ws:true,//用于支持websocket
pathRewrite:{"^/mySecondProxy":""}
}
}
}
})
发起请求:
<template>
<div>
<h1>欢迎访问员工管理页面</h1>
<button @click="sendRequestDemo()">访问后台服务器</button>
<button @click="sendRequestDemo2()">访问后台服务器使用多代理方式</button>
</div>
</template>
<script>
import axios from "axios"
export default {
name: "EmpDemo",
methods:{
sendRequestDemo2(){
//使用多代理服务器 根据代理服务器的名字 找具体的代理服务器发起代理请求
axios({
method:"get",
//http://127.0.0.1:8081/vueweb001/demo1/methodDemo.action
url:"http://localhost:9527/myFirstProxy/vueweb001/demo1/methodDemo1.action"
}).then(function(result){
alert(result.data)
console.log("myFirstProxy接收到的值:",result.data)
});
},
sendRequestDemo(){
//配置简单代理服务器 发起异步请求 访问后台服务器
axios({
method:"get",
配置简单代理服务器 请求资源时直接发给前端(8080)即可
//我们把请求发给前端服务器再由代理服务器帮我们转发到 8081服务器
url:"http://localhost:8080/vueweb001/demo1/methodDemo1.action"
}).then(function(result){
alert(result.data)
console.log(result.data)
});
}
}
}
</script>
<style scoped>
</style>