原文鏈接: https://blog.csdn.net/lhkuxia/article/details/119674392
跨域是什么?
出於瀏覽器的同源策略限制。
同源策略(Sameoriginpolicy) 是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能可能都會受到影響。
可以說Web是構建在同源策略基礎之上的,瀏覽器只是針對同源策略的一種實現。
同源策略會阻止一個域的javascript腳本和另外一個域的內容進行交互。所謂同源(即指在同一個域)就是兩個頁面具有相同的協議(protocol),主機(host)和端口號(port);
當一個請求url的協議、域名、端口三者之間任意一個與當前頁面url不同即為跨域
當前頁面url 被請求頁面url 是否跨域 原因
http://www.test.com/ http://www.test.com/index.html 否 同源(協議、域名、端口號相同)
http://www.test.com/ https://www.test.com/index.html 跨域 協議不同(http/https)
http://www.test.com/ http://www.baidu.com/ 跨域 主域名不同(test/baidu)
http://www.test.com/ http://blog.test.com/ 跨域 子域名不同(www/blog)
http://www.test.com:8080/ http://www.test.com:7001/ 跨域 端口號不同(8080/7001)
如何解決跨域(原理)
通過一些方法設置代理,在請求發送(接收)之前加入中間層,將不同的域名轉換成相同的,就解決了跨域的問題。客戶端發送請求時,不直接到服務器,而是先到代理的中間層
利用中間者去代理
1、瀏覽器給中間者發送請求
2、中間者把請求給到服務器
3、服務器發送結果給中間者
4、中間者發送結果給瀏覽器
1
2
3
4
在這里將http://localhost:8080的這個域名裝換為http://localhost:8081,
再將請求發送到服務器,這樣在服務器端收到的請求就是使用的http://localhost:8081;
同理,當服務器返回數據的時候,也是先到代理的中間層,
將http://localhost:8081轉換成http://localhost:8080,這樣在客戶端也是在同源下訪問的了。
實現-開發環境
假設接口域名為www.fuwuqi.cn。
vue-cli生成的配置文件上的proxyTable
1.在運行的時候,會配置啟動一個node服務,這個服務的作用:
1是靜態文件服務,讓你可以訪問到html/js等文件包括監聽文件變動等,
2是啟動一個http代理,你js發送的請求會請求到這個服務A,由服務A代理到服務B,而服務A和靜態文件服務器是同源的,並不影響同源策略。
2.瀏覽器是沒有必要設置CORS的,服務器設置CORS就是為了告知瀏覽器允許訪問我的源,不是跟我同源的,要在瀏覽器接受到響應后拋出錯誤。
vue-cli 4之前版本項目
先找到config/index.js,dev對象下的proxyTable中
寫法:
proxyTable: {
'/api': {
target: "www.fuwuqi.cn/api", // API服務器的地址
changeOrigin: true, // 如果設置為true,那么本地會虛擬一個服務器接收你的請求並代你發送該請求,這樣就不會有跨域問題(只適合開發環境)
pathRewrite: {
'^/api': '' // 重寫路徑 比如'/api/aaa/ccc'重寫為'/aaa/ccc'
}
}
},
1
2
3
4
5
6
7
8
9
vue-cli 4之后項目
需要新建vue.config.js 【默認情況下,4以上的版本可以直接識別這個js文件,把它當做自己的配置文件】
步驟如下:
1、在項目框架的根目錄下新建文件:vue.config.js
2、給新建的文件內添加解決跨域的代碼部分
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'https://域名/api',// API服務器的地址
ws: true, //代理websockets
changeOrigin: true, // 虛擬的站點需要更管origin
pathRewrite: { //重寫路徑 比如'/api/aaa/ccc'重寫為'/aaa/ccc'
'^/api': ''
}
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
3、重啟項目,這樣的話新建的文件就可以被識別了,一定要重啟
基於vite的項目
修改vite.config.js,在defineConfig中添加以下代碼
server:{
proxy:{
'/api': {
target: 'http://域名/api',
changeOrigin: true,
rewrite: path => path.replace(/^\/api/, '')
}
}
}
1
2
3
4
5
6
7
8
9
使用
this.$axios.post('/api/register',{ //最終相當於https://域名/api/register
}).then(function (res) {
console.log(res);
})
1
2
3
4
5
生產環境
保持前端不動,依舊是代理狀態
在項目打包部署后,原來的proxyTable就不能生效了,就需要使用Nginx或Apache進行反向代理;
這次使用的是寶塔面板進行部署項目配置反向代理
假設:
前端項目域名:www.qian.cn
后端項目域名:www.hou.cn
1
2
修改方法 1
1、新建網站,並上傳項目
2、點擊設置—》反向代理
3、添加反向代理,然后就ok了
假設接口的地址是:http://www.hou.com/api/index/index
代理名稱:可以隨便起,盡量跟代理目錄一致
代理目錄:就是域名后面的/api
目標URL:http://www.hou.com/api
發送域名:會自動生成
Apache
1. 修改Apache安裝目錄下的/conf/httpd.conf;或直接在面板這里修改:
2. 分別找到這兩行,把前面的注釋(#)去掉
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
1
2
3. 找到/www/server/panel/vhost/apache目錄下的www.qian.cn.conf
修改如下
<VirtualHost *:80>
ServerAdmin webmaster@example.com
DocumentRoot "/www/wwwroot/dist" #項目地址
ServerName 1bb943f9.www.qian.cn
ServerAlias www.qian.cn #前端地址域名
#errorDocument 404 /404.html
ErrorLog "/www/wwwlogs/www.qian.cn-error_log"
CustomLog "/www/wwwlogs/www.qian.cn-access_log" combined
#DENY FILES
<Files ~ (\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)$>
Order allow,deny
Deny from all
</Files>
#添加開始
ProxyRequests off
<Proxy *>
Order deny,allow
Allow from Off
</Proxy>
ProxyPass /api http://www.hou.cn/api # 前面是重新路徑,后面是代理到對應的地址
#添加結束
#PHP
<FilesMatch \.php$>
SetHandler "proxy:unix:/tmp/php-cgi-00.sock|fcgi://localhost"
</FilesMatch>
#PATH
<Directory "/www/wwwroot/dist">
SetOutputFilter DEFLATE
Options FollowSymLinks
AllowOverride All
Require all granted
DirectoryIndex index.php index.html index.htm default.php default.html default.htm
</Directory>
</VirtualHost>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
4. 保存並重啟Apache
Nginx
1. 修改Nginx安裝目錄下的/conf/nginx.conf;或直接在面板這里修改:
2. 找到/www/server/panel/vhost/nginx目錄下的www.qian.cn.conf
修改如下
server
{
listen 80;
server_name www.qian.cn;
index index.php index.html index.htm default.php default.htm default.html;
root /www/wwwroot/dist;
#跨域請求數據
location /api {
add_header "Access-Control-Allow-Origin" *;
proxy_pass http://www.hou.cn/api;
}
location @router {
rewrite ^.*$ /index.html last;
}
location / {
try_files $uri $uri/ @router;
index index.html;
}
#SSL-START SSL相關配置,請勿刪除或修改下一行帶注釋的404規則
#error_page 404/404.html;
#SSL-END
#ERROR-PAGE-START 錯誤頁配置,可以注釋、刪除或修改
#error_page 404 /404.html;
#error_page 502 /502.html;
#ERROR-PAGE-END
#PHP-INFO-START PHP引用配置,可以注釋或修改
include enable-php-00.conf;
#PHP-INFO-END
#REWRITE-START URL重寫規則引用,修改后將導致面板設置的偽靜態規則失效
include /www/server/panel/vhost/rewrite/www.qian.cn.conf;
#REWRITE-END
#禁止訪問的文件或目錄
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
{
return 404;
}
#一鍵申請SSL證書驗證目錄相關設置
location ~ \.well-known{
allow all;
}
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
error_log /dev/null;
access_log /dev/null;
}
location ~ .*\.(js|css)?$
{
expires 12h;
error_log /dev/null;
access_log /dev/null;
}
access_log /www/wwwlogs/er.kuxia.top.log;
error_log /www/wwwlogs/er.kuxia.top.error.log;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
3. 保存並重啟Nginx