当前位置:网站首页>跨域的五种解决方案
跨域的五种解决方案
2022-08-10 12:09:00 【祁_z】
跟多介绍可参考:
跨域的五种解决方案笔记和相关资料下载
1. 什么是跨域
浏览器不允许执行其他网站的脚步(ajax),浏览器的同源策略造成的;
例如:发起ajax请求时如果IP、端口、协议任一不同,则都属于跨域。
例如以下案例中,A网站需要请求B网站接口:
A网站 | B网站 | 是否跨域 | 说明 |
---|---|---|---|
http://192.162.1.1:8080 | http://192.162.2.2:8080 | 存在跨域 | IP不同 |
http://192.162.1.1:8080 | http://192.162.1.1:8081 | 存在跨域 | 端口不同 |
http://192.162.1.1:8080 | https://192.162.1.1:8080 | 存在跨域 | 协议不同 |
http://192.162.1.1:8080 | http://192.162.1.1:8080 | 不存在跨域 | (协议、ip、端口)全部相同 |
2. 演示跨域问题
步骤:
首先在右上角下载本章节相关资料;
- 将demo.html 放入Nginx的html目录中_(默认已经放进去了)_,双击nginx.exe启动Nginx, –启动Nginx
- 运行jar包
java -jar kexuekt01.jar
, 或通过idea打开kexuekt01项目, – 启动项目 - 浏览器访问:
http://127.0.0.1/demo.html
– 看效果
F12打开浏览器控制台查看跨域error错误信息`:
重要知识点:存在跨域时Java接口是可以正常进行业务处理的,只是浏览器不能接收后台返回的数据,并在图 1浏览器控制台输出的跨域错误。
3. 解决跨域的五种方法
- jsonp
- 内部HttpClient远程调用
- nginx反向代理
- 设置响应头允许跨域 response.setHeader(“Access-Control-Allow-Origin”, “*”);
- SpringBoot注解@CrossOrigin
3.1 Jsonp解决跨域演示
前端代码
$.ajax({
type:"get",
dataType:"jsonp",
jsonp:"callback",//请求中重写回调函数的名字
url:"http://127.0.0.1:8080/kexue/user",
success:function (data) {
alert(data.response);
}
}, 'json');
后台代码
- 后台需要接收的jsonp:"callback"中的"callback"参数,
- 返回参数格式必须为:callback({object});
@RequestMapping("/kexue/user")
public String demo(String callback) {
JSONObject obj = JSONUtil.createObj();
obj.put("code", 200);
obj.put("response", "调用成功");
// 返回格式:callback({object});
return callback + "(" + obj + ")";
}
说明
Jsonp的使用方式较为麻烦,解决跨域一般不会使用该方法。
3.2 内部HttpClient远程调用
启动两个后台
端口1:8080(自己公司的项目解决了跨域问题)
端口2:8081(模拟第三方项目接口,没有解决跨域问题)
8080端口项目
@CrossOrigin // 跨域注解
@RestController
public class Demo1 {
@RequestMapping("/kexue/user")
public JSONObject demo() {
String body = HttpRequest.get("127.0.0.1:8081/kexue/user2").execute().body();
JSONObject obj = JSONUtil.parseObj(body);
return obj;
}
}
8081端口项目(第三方接口)
@RequestMapping("/kexue/user2")
public JSONObject demo() {
JSONObject obj = JSONUtil.createObj();
obj.put("code", 200);
obj.put("response", "第三方接口");
return obj;
}
注:修改端口号,便于测试 -Dserver.port=8081
说明
HttpClient这种方式适合调用第三方接口。
例如:调用第三方接口时,如果前端直接调用第三方接口会报跨域问题(第三方接口没有解决跨域问题),那么就只能通过后台HttpClient的方式进行调用。
3.3 Nginx反向代理
前端代码
$.ajax({
type:"get",
url:"http://127.0.0.1:80/kexue/user",
success:function (data) {
//请求成功后的处理
alert(data.response);
}
}, 'json');
后端代码
@RequestMapping("/kexue/user")
public JSONObject demo() {
JSONObject obj = JSONUtil.createObj();
obj.put("code", 200);
obj.put("response", "调用成功");
// 返回格式:callback({object});
return obj;
}
nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
#拦截所有以/kexue开头的请求
location /kexue {
index proxy_set_header Host $host;
index proxy_set_header X-Real-IP $remote_addr;
index proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:8080; #后端服务地址
}
}
}
说明
使用Nginx方向代理的前提是,前端代码(vue)需要和Nginx服务在一台物理机上;如果满足以上条件,就优先考虑通过Nginx反向代理来解决跨域问题。
3.4 设置响应头允许跨域
前端代码
$.ajax({
type:"get",
url:"http://127.0.0.1:8080/kexue/user",
success:function (data) {
//请求成功后的处理
alert(data.response);
}
}, 'json');
后端代码
@RequestMapping("/kexue/user")
public JSONObject demo(HttpServletResponse response) {
JSONObject obj = JSONUtil.createObj();
obj.put("code", 200);
obj.put("response", "调用成功");
// *允许所有网站跨域
response.setHeader("Access-Control-Allow-Origin", "*");
return obj;
}
说明
通常都是在拦截器中来配置“设置响应头允许跨域”。
3.5 @CrossOrigin注解
前端代码
$.ajax({
type:"get",
url:"http://127.0.0.1:8080/kexue/user",
success:function (data) {
//请求成功后的处理
alert(data.response);
}
}, 'json');
后端代码
@CrossOrigin // 跨域注解
@RestController
public class Demo1 {
@RequestMapping("/kexue/user")
public JSONObject demo() {
JSONObject obj = JSONUtil.createObj();
obj.put("code", 200);
obj.put("response", "调用成功");
return obj;
}
}
说明
@CrossOrigin注解底层通过Spring的拦截器功能往response里添加 Access-Control-Allow-Origin等响应头信息。
response.setHeader(“Access-Control-Allow-Origin”, “*”);
个人博客首页 祁_z
原创不易,感觉对自己有用的话就️点赞收藏评论把。
边栏推荐
- CURRENT_TIMESTAMP(6) 函数是否存在问题?
- 自定义过滤器和拦截器实现ThreadLocal线程封闭
- How to do foreign media publicity to grasp the key points
- 堪称神级的阿里巴巴“高并发”教程——基础+实战+源码+面试+架构 全包了
- 用低代码驱动IT现代化
- Educational Codeforces Round 41 (Rated for Div. 2) E. Tufurama
- An enhanced dynamic packet buffer management. The core part of the paper
- 11 + chrome advanced debugging skills, learn to direct efficiency increases by 666%
- 日记16
- 浮动及其特点
猜你喜欢
Guo Jingjing's personal chess teaching, the good guy is a robot
面试美团被问到了Redis,搞懂这几个问题,让你轻松吊打面试官
自定义过滤器和拦截器实现ThreadLocal线程封闭
Polygon zkEVM工具——PIL和CIRCOM
StarRocks on AWS 回顾 | Data Everywhere 系列活动深圳站圆满结束
IDC第一的背后,阿里云在打造怎样的一朵“视频云”?
A detailed explanation of implementation api embed
dedecms supports one-click import of Word content
2022年8月中国数据库排行榜:openGauss重夺榜眼,PolarDB反超人大金仓
爱可可AI前沿推介(8.10)
随机推荐
How to cultivate the design thinking of ui designers?
解决 idea 单元测试不能使用Scanner
郭晶晶家的象棋私教,好家伙是个机器人
Can CLIP also do segmentation tasks?The University of Göttingen proposed a model CLIPSeg that uses text and image prompts to perform three segmentation tasks at the same time, draining CLIP capabiliti
阿里云贾朝辉:云XR平台支持彼真科技呈现国风科幻虚拟演唱会
Codeforces Round #276 (Div. 1) D. Kindergarten
Servlet---Solve the problem of Chinese garbled characters in post requests
什么是云流化?
堪称神级的阿里巴巴“高并发”教程——基础+实战+源码+面试+架构 全包了
StarRocks on AWS 回顾 | Data Everywhere 系列活动深圳站圆满结束
用低代码驱动IT现代化
LT8911EXB MIPI CSI/DSI转EDP信号转换
47Haproxy集群
爱可可AI前沿推介(8.10)
百度用户产品流批一体的实时数仓实践
MySQL索引的B+树到底有多高?
The god-level Alibaba "high concurrency" tutorial - basic + actual combat + source code + interview + architecture is all-inclusive
search--09
Real-time data warehouse practice of Baidu user product flow and batch integration
Chapter 5 virtual memory