前言
什么是跨域?
浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域
为什么会有跨域?
在前后端分离的模式下,前后端的域名是不一致的,此时就会发生跨域访问问题。在请求的过程中我们要想获取数据一般都是post/get请求,所以…跨域问题出现
跨域的作用在于:保证不同服务之间的数据安全,比如黑客在A服务给B服务发送了一个请求,恰好B服务又是登陆状态,那样就会携带B的session等信息返回
跨域问题来源于JavaScript的同源策略,即只有 协议+主机名+端口号(如存在)相同,则允许相互访问。也就是说JavaScript只能访问和操作自己域下的资源,不能访问和操作其他域下的资源。跨域问题是针对JS和ajax的,html本身没有跨域问题,比如a标签、script标签、甚至form标签(可以直接跨域发送数据并接收数据)等
跨域解决方案
一、后台解决方案
1、添加响应头
@RestController
public void UserController {
@RequestMapping("/user")
public User getUser(HttpServletRespone response) {
response.addHeader("Access-Control-Allow-Origin", "http://127.0.0.1:8081");
return new User();
}
}
或者直接使用Springboot注解@CrossOrigin
2、手动代理类
@RequestMapping("/api/**")
public Object proxy(httpServletRequest request) {
return restTemplate.getFotObject(proxyAddress + request.getRequestURI().replace("/api", ""), Object.class);
}
URI:Uniform Resource Identifier,统一资源标识符
URL:Uniform Resource Locator,统一资源定位器
URN:永久统一资源定位符,在资源移动之后还能找到
二、前端解决方案
1、nginx
正向代理:明确访问目标(访问真实目标地址),但是用户不知道中间代理服务器
反向代理:访问代理服务器地址,然后代理服务器选择一台后台服务器获取数据
server{
listen 80;
server_name localhost;
location /api {
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http:127.0.0.1:8081;
}
}
2、jsonp
在
后台请求:
@RequestMapping("/cross")
public String cross() {
return "cross(123)"
}
前端:
<body>
<script>
function cross(data) {
console.log(data)
}
</script>
<script src="http:127.0.0.1:8081/cross"></script>
</body>
最终页面会输出:123
总结
跨域请求是浏览器限制,防止你的http请求被他人滥用,通过curl工具依然可以获取到响应