Python的Django應用程序解決AJAX跨域訪問問題的方法
引子
使用Django在服務器端寫了一個API,返回一個JSON數(shù)據(jù)。使用Ajax調(diào)用該API:
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width,initial-scale=1.0"/> <title>test</title> </head> <body> <button onclick="showPersonInfo()">點我獲取數(shù)據(jù)</button> </body> <script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script> <script> function showPersonInfo(){ $.getJSON( 'http://xxx/account/getuserinfo/', {username: "abc"}, function(json) { var html='<br>'+'用戶名:'+json.username+'<br>'+'姓:'+json.first_name+'<br>'+'名:'+json.last_name+'<br>'+'郵箱'+json.email; document.write(html); } ) } </script> </html>
但是,Chrome瀏覽器提示錯誤:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
經(jīng)過一番Google發(fā)現(xiàn)這個問題是——CORS導致的。
什么是CORS?
CORS(跨域資源共享,Cross-Origin Resource Sharing)是一種跨域訪問的機制,可以讓Ajax實現(xiàn)跨域訪問。
其實,在服務器的response header中,加入“Access-Control-Allow-Origin: *”即可支持CORS,非常的簡單,apache/nginx等怎么配置,見參考文檔。
舉個例子:
- API部署在DomainA上;
- Ajax文件部署在DomainB上,Ajax文件會向API發(fā)送請求,返回數(shù)據(jù);
- 用戶通過DomainC訪問DomainB的Ajax文件,請求數(shù)據(jù)
以上過程就發(fā)生了跨域訪問。如果直接使用Ajax來請求就會失敗,就像Chrome提示的:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
如何解決Ajax跨域訪問問題?
解決跨域問題,有兩個方法:1.使用jsonp 2.使CORS生效
使用jsonp方法,需要讓服務器端放回jsonp格式的response,如Django可以加jsonp相關(guān)的decorator,如:https://coderwall.com/p/k8vb_a/returning-json-jsonp-from-a-django-view-with-a-little-decorator-help由于我不太喜歡這種方式,所以這里略過了,可看后面的參考資料。
使用CORS:這個用起來比較方便,現(xiàn)在大多數(shù)瀏覽器都支持了,且我web服務器完全開放給別人調(diào)用,所以比較推薦CORS。
1.使用JSONP
使用Ajax獲取json數(shù)據(jù)時,存在跨域的限制。不過,在Web頁面上調(diào)用js的script腳本文件時卻不受跨域的影響,JSONP就是利用這個來實現(xiàn)跨域的傳輸。因此,我們需要將Ajax調(diào)用中的dataType從JSON改為JSONP(相應的API也需要支持JSONP)格式。
JSONP只能用于GET請求。
2.直接修改Django中的views.py文件
修改views.py中對應API的實現(xiàn)函數(shù),允許其他域通過Ajax請求數(shù)據(jù):
def myview(_request): response = HttpResponse(json.dumps({"key": "value", "key2": "value"})) response["Access-Control-Allow-Origin"] = "*" response["Access-Control-Allow-Methods"] = "POST, GET, OPTIONS" response["Access-Control-Max-Age"] = "1000" response["Access-Control-Allow-Headers"] = "*" return response
3.安裝django-cors-headers
這里還有一各發(fā)現(xiàn)!在Django中,有人開發(fā)了CORS-header的middleware,只在settings.py中做一些簡單的配置即可,見:https://github.com/ottoyiu/django-cors-headers/現(xiàn)在用起來服務器端完全開放,開啟CORS,沒有跨域煩惱,真爽!~
安裝django-cors-headers:
pip install django-cors-headers
在settings.py中增加:
INSTALLED_APPS = ( ... 'corsheaders', ... ) ... MIDDLEWARE_CLASSES = ( ... 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', ... )
可以配置允許跨域訪問的白名單或者直接設(shè)置為允許所有的跨域訪問,具體的配置可以看看他們的github頁說明。
相關(guān)文章
python編程-將Python程序轉(zhuǎn)化為可執(zhí)行程序[整理]
python編程-將Python程序轉(zhuǎn)化為可執(zhí)行程序[整理]...2007-04-04python正則表達式re之compile函數(shù)解析
這篇文章主要介紹了python正則表達式re之compile函數(shù)解析,介紹了其定義,匹配模式等相關(guān)內(nèi)容,具有一定參考價值,需要的朋友可以了解下。2017-10-10