針對Django中在編寫供AJAX調用的API時碰到的跨域問題,我們來總結下Python的Django應用程式解決AJAX跨域訪問問題的方法,其中使用GitHub上開源分享的django-cors- headers尤其推薦
引子
使用Django在伺服器端寫了一個API,回傳一個JSON資料。使用Ajax呼叫該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()">点我获取数据</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.
經過一番Google發現這個問題是-CORS導致的。
什麼是CORS?
CORS(跨域資源共享,Cross-Origin Resource Sharing)是一種跨域存取的機制,可以讓Ajax實現跨域存取。
其實,在伺服器的response header中,加入「Access-Control-Allow-Origin: *」即可支援CORS,非常的簡單,apache/nginx等怎麼配置,請參閱參考文件。
舉例:
API部署在DomainA上;
Ajax檔案部署在DomainB上,Ajax檔案會向API發送請求,返回資料;
用戶透過DomainC存取DomainB的Ajax文件,請求資料
以上過程就發生了跨域存取。如果直接使用Ajax來請求就會失敗,就像Chrome提示的:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
如何解決Ajax跨域存取問題?
解決跨域問題,有兩個方法:1.使用jsonp 2.使CORS生效
使用jsonp方法,需要讓伺服器端放回jsonp格式的response,如Django可以加jsonp相關的decorator,如:http://www.php.cn/由於我不太喜歡這種方式,所以這裡略過了,可看後面的參考資料。
使用CORS:這個用起來比較方便,現在大多數瀏覽器都支援了,而且我web伺服器完全開放給別人調用,所以比較推薦CORS。
1.使用JSONP
使用Ajax取得json資料時,存在跨域的限制。不過,在Web頁面上呼叫js的script腳本檔案時卻不受跨域的影響,JSONP就是利用這個來實現跨域的傳輸。因此,我們需要將Ajax呼叫中的dataType從JSON改為JSONP(對應的API也需要支援JSONP)格式。
JSONP只能用於GET請求。
2.直接修改Django中的views.py檔案
修改views.py中對應API的實作函數,讓其他網域透過Ajax請求資料:
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
這裡還有一各發現!在Django中,有人開發了CORS-header的middleware,只在settings.py中做一些簡單的配置即可,請參閱:http://www.php.cn/現在用起來伺服器端完全開放,開啟CORS,沒有跨域煩惱,真爽! ~
安裝django-cors-headers:
pip install django-cors-headers
#在settings.py中增加:
INSTALLED_APPS = ( ... 'corsheaders', ... ) ... MIDDLEWARE_CLASSES = ( ... 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', ... )
可以設定允許跨網域訪問的白名單或直接設定為允許所有的跨網域訪問,具體的配置可以看看他們的github頁說明。
更多Python的Django應用程式解決AJAX跨域訪問相關文章請關注PHP中文網!