Flask框架踩坑之a(chǎn)jax跨域請求實現(xiàn)
業(yè)務(wù)場景:
前后端分離需要對接數(shù)據(jù)接口。
接口測試是在postman做的,今天才開始和前端對接,由于這是我第一次做后端接口開發(fā)(第一次嘛,問題比較多)所以在此記錄分享我的踩坑之旅,以便能更好的理解,應(yīng)用。
問題:
前端ajax請求后端接口出現(xiàn)跨域問題,如下圖。
翻譯:因為響應(yīng)頭沒有"Access-Control-Allow-Origin",所以接口拒絕把數(shù)據(jù)返回給前端。
什么是Access-Control-Allow-Origin?
Access-Control-Allow-Origin是HTML5中定義的一種解決資源跨域的策略。
瀏覽器只允許請求當前域的資源,而對其他域的資源表示不信任。那怎么才算跨域呢?
- 請求協(xié)議
http,https
的不同 - 域
domain
的不同 - 端口
port
的不同
其實說簡單點,跨域,指的就是瀏覽器不能執(zhí)行其他網(wǎng)站的腳本。它是由瀏覽器的同源策略造成的,是瀏覽器施加的安全限制。
同源是指:協(xié)議相同,域名相同,端口相同。三者同時成立才能叫同源。
瀏覽器的同源策略從它誕生的那一刻就出現(xiàn)了,具體是指從域名A下的一個頁面(一般是通過ajax請求)獲取域名B下的一個資源,是不被瀏覽器允許的。
跨域資源共享(CORS)是瀏覽器提供的一種跨域協(xié)商機制,讓前后端協(xié)商是否可以發(fā)出跨域請求。CORS添加了若干Access-controll-request-xxx 的頭,給客戶端聲明自己的源、要使用的頭部、用使用的請求方法;添加了若干Access-Controll-Allow-xxx的頭,給服務(wù)端聲明自己支持跨域的源、頭部和方法。
URL | 說明 | 是否允許通信 |
---|---|---|
http://www.a.com/a.js http://www.a.com/b.js |
同一域名下 | 允許 |
http://www.a.com/lab/a.js http://www.a.com/script/b.js |
同一域名下不同文件夾 | 允許 |
http://www.a.com:8000/a.js http://www.a.com/b.js |
同一域名,不同端口 | 不允許 |
http://www.a.com/a.js https://www.a.com/b.js |
同一域名,不同協(xié)議 | 不允許 |
http://www.a.com/a.js http://70.32.92.74/b.js |
域名和域名對應(yīng)ip | 不允許 |
http://www.a.com/a.js http://script.a.com/b.js |
主域相同,子域不同 | 不允許 |
http://www.a.com/a.js http://a.com/b.js |
同一域名,不同二級域名(同上) | 不允許(cookie這種情況下也不允許訪問) |
http://www.cnblogs.com/a.js http://www.a.com/b.js |
不同域名 | 不允許 |
解決方案(從后端解決)
1.后臺接口允許跨域請求
以Python Flask框架為例,有兩種方法。
第一種第三方插件實現(xiàn),只需要安裝第三方插件就可以輕松地為所有接口添加響應(yīng)頭。
pip3 install flask-cors
from flask_cors import * app = Flask(__name__) # r'/*' 是通配符,讓本服務(wù)器所有的URL 都允許跨域請求 CORS(app, resources=r'/*')
實際上就是為接口響應(yīng)頭添加了一個Access-Control-Allow-Origin并設(shè)置值*表示所有網(wǎng)站都可以請求。
第二種接口函數(shù)自定義添加屬性。
res.headers['Access-Control-Allow-Origin'] = '*' return res
為返回結(jié)果res屬性headers設(shè)置Access-Control-Allow-Origin值為*。只對當前接口有效。
2.利用nginx反向代理
說到nginx,不得不說真的很強大,也帶來很多便利用于解決一些頭疼的難題。
一般來說可以用來做:靜態(tài)頁面的服務(wù)器、靜態(tài)文件緩存服務(wù)器、網(wǎng)站反向代理、負載均衡服務(wù)器等等,而且實現(xiàn)這一切,基本只需要改改那萬能的配置文件即可。
server { listen 80; server_name localhost; location / { proxy_pass http://localhost:81; proxy_redirect default; } location /apis { #添加訪問目錄為/apis的代理配置 rewrite ^/apis/(.*)$ /$1 break; proxy_pass http://localhost:82; } }
1.由配置信息可知,我們讓nginx監(jiān)聽localhost的80端口,本地的81端口有都是經(jīng)過localhost的80端口進行訪問。
2.我們特殊配置了一個“/apis”目錄的訪問,并且對url執(zhí)行了重寫,最后使以“/apis”開頭的地址都轉(zhuǎn)到“http://localhost:82”進行處理。
3.rewrite ^/apis/(.*)$ /$1 break,代表重寫攔截進來的請求,并且只能對域名后邊以“/apis”開頭的起作用,例如www.a.com/apis/msg?x=1重寫。只對/apis重寫。rewrite后面的參數(shù)是一個簡單的正則 ^/apis/(.*)$ ,$1代表正則中的第一個(),$2代表第二個()的值,以此類推。break代表匹配一個之后停止匹配。
總結(jié)一下,搭建一個nginx并把相應(yīng)代碼部署在服務(wù)器本機,由頁面請求本域名的一個地址,轉(zhuǎn)由nginx代理到目標服務(wù)器處理后返回結(jié)果給頁面。這樣就完美解決了跨域問題。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
python實現(xiàn)文件名批量替換和內(nèi)容替換
這篇文章主要介紹了python實現(xiàn)文件名批量替換和內(nèi)容替換,第一個例子可以指定文件類型,需要的朋友可以參考下2014-03-03使用Python腳本來控制Windows Azure的簡單教程
這篇文章主要介紹了使用Python腳本來控制Windows Azure的簡單教程,由于微軟官方提供了Python SDK,使得用戶自己用Python控制Azure成為了可能,需要的朋友可以參考下2015-04-04