PythonのDjangoアプリケーションはAJAXドメイン間のアクセス問題を解決する方法です。

3805 ワード

誘引子
Djangoを使ってサーバーの端にAPIを書き、JSONデータを返します。APIは、Ajaxを使用して起動される:

<!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にクロスドメインアクセスを実現させることができる。
実は、サーバーのレスポンスheaderに「Access-Coontrol-Origin:*」を入れるとCORSがサポートされます。とても簡単です。
例を挙げます
  • APIはDomainAに展開されている。
  • AjaxファイルはDomainBに展開され、AjaxファイルはAPIに要求を送信し、データを返す。
  • ユーザはDomainCを通じてDomainBのAjaxファイルにアクセスし、要求データ
  • 以上の過程でクロスドメインアクセスが発生しました。直接Ajaxを使って請求すると失敗します。Chromeが提示したように。
    
    No 'Access-Control-Allow-Origin' header is present on the requested resource.
    
    
    Ajaxクロスドメインアクセス問題はどう解決しますか?
    クロスドメイン問題を解決するには、2つの方法があります。1.jsop 2を使って、CORSを有効にします。
    jsonpメソッドを使用すると、Djangoなどのjsonp関連のdecoratorを追加することができます。https://coderwall.com/p/k8vb_a/returning-json-json-from-a-django-view-with-a-little-decorator-helpは私はこのような方式があまり好きではないので、ここで略して、後の参考資料を見ることができます。
    CORSを使います。これは使いやすいです。今はほとんどのブラウザがサポートしています。また、webサーバは完全に開放されていますので、CORSをオススメします。
    1.JSONPを使う
    Ajaxを使ってJsonデータを取得する場合、ドメインをまたぐ制限があります。しかし、jsのスクリプトファイルをWebページで呼び出す際はドメインをまたぐ影響を受けず、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-cords-headersをインストールする
    ここでもう一つ発見があります。Djangoでは、CORS-headerのmiddlewareを開発した人がいます。settings.pyの中で簡単な配置をすればいいです。https://github.com/ottoyiu/django-cors-headers/今使ってサーバーの端が完全に開放されて、CORSを開いて、ドメインをまたぐ悩みがなくて、本当にさわやかです!
    django-cords-headersをインストールします。
    
    pip install django-cors-headers
    
    settings.pyに追加:
    
    INSTALLED_APPS = (
      ...
      'corsheaders',
      ...
    )
    
    ...
    
    MIDDLEWARE_CLASSES = (
      ...
      'corsheaders.middleware.CorsMiddleware',
      'django.middleware.common.CommonMiddleware',
      ...
    )
    
    
    ドメインをまたぐアクセスが可能なホワイトリストを設定したり、ドメインをまたぐすべてのアクセスを許可するように直接設定したりすることができます。