1. 程式人生 > >用django-cors-headers做跨域

用django-cors-headers做跨域

什麼是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提示的:

?

1

No 'Access-Control-Allow-Origin' header is present on the requested resource.

如何解決Ajax跨域訪問問題?
解決跨域問題,有兩個方法:1.使用jsonp 2.使CORS生效
使用jsonp方法,需要讓伺服器端放回jsonp格式的response,如Django可以加jsonp相關的decorator,如:https://coderwall.com/p/k8vb_a/returning-json-jsonp-from-a-django-view-with-a-little-decorator-help由於我不太喜歡這種方式,所以這裡略過了,可看後面的參考資料。
使用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請求資料:

?

1

2

3

4

5

6

7

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中做一些簡單的配置即可,見:https://github.com/ottoyiu/django-cors-headers/現在用起來伺服器端完全開放,開啟CORS,沒有跨域煩惱,真爽!~
安裝django-cors-headers:

?

1

pip install django-cors-headers

在settings.py中增加:

 

INSTALLED_APPS = (

  ...

  'corsheaders',

  ...

)

 

...

 

MIDDLEWARE_CLASSES = (

  ...

  'corsheaders.middleware.CorsMiddleware',

  'django.middleware.common.CommonMiddleware',

  ...

)

#跨域增加忽略

CORS_ALLOW_CREDENTIALS = True

CORS_ORIGIN_ALLOW_ALL = True

CORS_ORIGIN_WHITELIST = ( '*' )

CORS_ALLOW_METHODS = (

        'DELETE',

        'GET',

        'OPTIONS',

        'PATCH',

        'POST',

        'PUT',

        'VIEW',

)

CORS_ALLOW_HEADERS = (

        'XMLHttpRequest',

        'X_FILENAME',

        'accept-encoding',

        'authorization',

        'content-type',

        'dnt',

        'origin',

        'user-agent',

        'x-csrftoken',

        'x-requested-with',

        'Pragma',

)