跨域问题解决方案
·
一、什么是跨域
1、定义
跨域指的是从一个域名的网页去请求另一个域名的资源时,如果域名、端口、协议任一不同,都是跨域。在前端领域中,跨域是指浏览器允许向服务器发送跨域请求,从而克服Ajax只能同源使用的限制。
同源策略是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同, 即便两个不同的域名指向同一个ip地址,也非同源。
2、原因
跨域是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制。同源策略要求协议、域名、端口都要相同,其中有一个不同都会产生跨域。
3、影响
跨域限制访问是浏览器的限制,旨在防止恶意网站通过一个域的网页访问另一个域的敏感数据。没有同源策略,浏览器的许多功能可能无法正常工作。
4、示例
例如,a页面想获取b页面资源,如果a、b页面的协议、域名、端口、子域名不同,所进行的访问行动都是跨域的,浏览器为了安全问题会限制这种访问


二、怎么解决跨域问题
1、前端
1.1 jsonp
ajax实现方式
$.ajax({
url: 'http://www.domain2.com:8080/login',
type: 'get',
dataType: 'jsonp', // 请求方式为jsonp
jsonpCallback: "handleCallback", // 自定义回调函数名
data: {}
});
axios实现方式
this.$http = axios;
this.$http.jsonp('http://www.domain2.com:8080/login', {
params: {},
jsonp: 'handleCallback'
}).then((res) => {
console.log(res);
})
虽然jsonp可以实现跨域,但是因为jsonp不支持post请求,应用场景受到很大限制
1.2 代理
vue项目配置
changeOrigin: true
devServer: {
host: '0.0.0.0',
port: port,
open: true,
proxy: {
// detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: {
target: `http://localhost:8080`,
changeOrigin: true,
pathRewrite: {
['^' + process.env.VUE_APP_BASE_API]: ''
}
}
},
开发环境的跨域,也就是在vue-cli脚手架环境下开发启动服务时,我们访问接口所遇到的跨域问题,vue-cli为我们在本地开启了一个服务,可以通过这个服务帮我们代理请求,解决跨域问题。访问devServer 让devServer去访问服务器
vue-cli的配置文件即vue.config.js
https://cli.vuejs.org/zh/config/#devserver-proxy
module.exports = {
devServer: {
// 代理配置
proxy: {
// 这里的api 表示如果我们的请求地址有/api的时候,就出触发代理机制
// localhost:8888/api/abc => 代理给另一个服务器
// 本地的前端 =》 本地的后端 =》 代理我们向另一个服务器发请求 (行得通)
// 本地的前端 =》 另外一个服务器发请求 (跨域 行不通)
'/api': {
target: 'http://ihrm.itheima.net', // 我们要代理的地址
changeOrigin: true, // 是否跨域 需要设置此值为true 才可以让本地服务代理我们发出请求
}
},
}
}
2、后台(CORS)
2.1 单个控制器方法CORS注解
@RestController
@RequestMapping("/system/test")
public class TestController {
@CrossOrigin
@GetMapping("/{id}")
public AjaxResult getUser(@PathVariable Integer userId) {
// ...
}
@DeleteMapping("/{userId}")
public AjaxResult delete(@PathVariable Integer userId) {
// ...
}
}
2.2 整个控制器启用CORS注解
@CrossOrigin(origins = "http://ruoyi.vip", maxAge = 3600)
@RestController
@RequestMapping("/system/test")
public class TestController {
@GetMapping("/{id}")
public AjaxResult getUser(@PathVariable Integer userId) {
// ...
}
@DeleteMapping("/{userId}")
public AjaxResult delete(@PathVariable Integer userId) {
// ...
}
}
2.3 全局CORS配置
/**
* web跨域访问配置
*/
@Override
public void addCorsMappings(CorsRegistry registry)
{
// 设置允许跨域的路径
registry.addMapping("/**")
// 设置允许跨域请求的域名
.allowedOrigins("*")
// 是否允许证书
.allowCredentials(true)
// 设置允许的方法
.allowedMethods("GET", "POST", "DELETE", "PUT")
// 设置允许的header属性
.allowedHeaders("*")
// 跨域允许时间
.maxAge(3600);
}
3、代理
使用Nginx解决跨域,配置Nginx的反向代理
location / {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
if ($request_method = 'OPTIONS') {
return 204;
}
proxy_pass http://192.168.12.1:8081;
}
更多推荐



所有评论(0)