前端跨域,nginx反向代理的解決方案
現在越來越多的公司開始使用前后端分離的技術,而盲目的分離是不理智的,跨域也是第一難題。我的第一份工作就是公司第一個以前端開發者的身份入職,此時公司所有的項目都已正式運行了(項目太多,結構復雜,團隊分散,后台不能改)
先了解一下為什么跨域:
1.瀏覽器先根據同源策略對前端頁面和后台交互地址做匹配,若同源,則直接發送數據請求;若不同源,則發送跨域請求。
2.服務器解析程序收到瀏覽器跨域請求后,根據自身配置返回對應文件頭。若未配置過任何允許跨域,則文件頭里不包含Access-Control-Allow-origin字段,若配置過域名,則返回Access-Control-Allow-origin+ 對應配置規則里的域名的方式。
3.瀏覽器根據接受到的http文件頭里的Access-Control-Allow-origin字段做匹配,若無該字段,說明不允許跨域;若有該字段,則對字段內容和當前域名做比對,如果同源,則說明可以跨域,瀏覽器發送該請求;若不同源,則說明該域名不可跨域,不發送請求
總結一下跨域的原因就是一句話:不同IP或不同端口就是跨域。想了解更詳細的可以去查查別人的資料。
所以想要解決跨域的方法就是讓服務器追加該前端的域名。
后台不加怎么辦?以下就是解決方案之一:
讓前端頁面和后台交互地址同源。
Nginx代理方式
這里所說的代理是指前端的代理,跟后端沒什么關系
修改nginx.conf配置文件
server {
listen 80;
server_name http://localhost;
location / {
root D:\test;
index index.html index.htm;
}
}
這里是代理了一個本地項目,開通80端口訪問,root是本地項目路徑,index是項目的入口文件。
我只貼了主要的地方,404、500之類的東西可以參考別人或看官方文檔。
如果你的前端采用的node.js之類的服務器運行的話
location / {
proxy_pass http://localhost:8080;
}
這也已經是反向代理了,使用80端口就可以訪問8080端口的前端頁面了。
Nginx反向代理
進入正題,在同一配置文件下加點東西
location /test{
rewrite ^.+test/?(.*)$ /$1 break;
proxy_pass http://localhost:8090;
}
這是反向代理了8090端口的服務器,/test作為標識指向該服務器,rewrite重定向URL,將/test刪除掉。
講解下使用方法
讓前端頁面和后台交互地址同源的意思就是:
1.打開前端頁面的地址是:http://localhost:80
2.請求的后台地址也是:http://localhost:80
在上面的配置中 /test 作為標識,http://localhost:80/test 指向的就是 http://localhost:8090 這台服務器,rewrite 把 test/ 給刪除了,所以不會影響路徑而導致地址錯誤。
所以在前端向后台發送接口請求的時候一定要注意了:
$.ajax({
url:'http://localhost:80/test/url', // /test代表8090服務器
type:'post',
async:true,
data:{},
timeout:5000,
dataType:'json',
success:function(data,textStatus,jqXHR){
console.log(JSON.stringify(data))
},
error:function(xhr,textStatus){
console.log('錯誤')
}
})
http://localhost:80/test 代表的服務器的IP,/url 就是接口的詳細路徑。
重要:
訪問前端的頁面時采用的是域名訪問,這里的后台接口必需也是域名:http://www.aa.com:80/test/url;
如果是IP訪問,相應的也要改成 http://192.168.199.1:80/test/url,請留意!
隨手寫的一份Nginx配置文件
server {
listen 80;
server_name http://localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location /test {
rewrite ^.+test/?(.*)$ /$1 break;
proxy_pass http://localhost:8090;
}
location /Additional {
rewrite ^.+Additional/?(.*)$ /$1 break;
proxy_pass http://localhost:8091;
}
location / {
root D:\test;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
可以相應追加更多需要用到的服務器
location /Additional {
rewrite ^.+Additional/?(.*)$ /$1 break;
proxy_pass http://localhost:8091;
}
小結:nginx反向代理絕對不是解決跨域的最佳方案,在開發、測試、正式環境下都需要配置相應的配置文件,萬一后台的IP或端口改變都需要修改配置文件,而且作為反向代理它不過是做了一個跳轉,在速度上是要比直連要慢的,性能也會有影響。跟后台的人好好商量,能改后台就該后台,吃頓飯喝頓酒,不行還有py呢!
