網站首頁 編程語言 正文
跟多介紹可參考:
跨域的五種解決方案筆記和相關資料下載
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”, “*”);
原文鏈接:https://blog.csdn.net/qq_36881887/article/details/125457820
相關推薦
- 2022-07-03 C#入門之結構類型Struct_C#教程
- 2022-05-11 Restful的Get請求參數為List
- 2022-05-23 c++?qt自定義搜索編輯框的實現方法_C 語言
- 2022-07-22 如何處理SQL Server中附加數據庫時出現的錯誤
- 2022-09-22 使用 sed 替換字符串中最后一次出現的字符
- 2022-08-21 Android自定義view貝塞爾曲線_Android
- 2023-06-16 C語言函數調用底層實現原理分析_C 語言
- 2022-12-07 C++中new的用法及說明_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支