2017-12-07 3 views
3

私はウェブプログラミングには初めてですので、私に同行してください。私はPythonフラスコで簡単なREST APIを作成し、Apache 2.4でそれをホストしています。私はcURLを介してそれをテストし、それは動作します。今、私はjQueryを使ってWebインターフェイス経由でアクセスしようとしています。クロスドメインREST POSTはプリフライトチェックを行いますが、フォローアップしません

REST APIはhttp://api.localhostにあり、アクセスするウェブサイトはhttp://localhostです。

私はPOSTを試してみませんかするために使用しているコードは次のようになります。

$.ajax({ 
     type: 'POST', 
     url: 'http://api.localhost/auth', 
     data: '{"username":"user1", "password":"abcxyz"}', 
     success: function(data) { console.log(data); alert('data: ' + data); }, 
     contentType: "application/json", 
     dataType: 'json' 
    }); 

しかし、成功の関数が実行されませんようです。 devコンソール(f12)を見ると、そのURLへのPOSTではなく、OPTIONS HTTP要求が行われていることがわかります。私が理解するのは、ローカルホストがapi.localhostにアクセスできることを確認するために、これはクロスソースリソース共有(CORS)のプリフライトチェックです。

私はapi.localhostのための私のApache設定に次の行を追加しました:

Header always set Access-Control-Allow-Origin "*" 
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS" 

これは、OPTIONS要求は200(および他のデータ)を返すために動作しているようです。ただし、フォローアップはありません。私の理解は、サーバーがapi.localhostにPOSTすることは誰でもOKだと言っているので、次にPOSTを実行する必要がありますが、そうはしません。ここで

は、プリフライトチェックリクエストヘッダです:ここ

Host: api.localhost 
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 
Firefox/52.0 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: en-US,en;q=0.5 
Accept-Encoding: gzip, deflate 
Access-Control-Request-Method: POST 
Access-Control-Request-Headers: content-type 
Origin: http://localhost 
Connection: keep-alive 
Cache-Control: max-age=0 

は、同じ要求に対する応答ヘッダは(ステータス200を覚えている)、次のとおりです。

Access-Control-Allow-Methods: POST, GET, OPTIONS 
Access-Control-Allow-Origin: * 
Allow: POST, OPTIONS 
Connection: Keep-Alive 
Content-Encoding: gzip 
Content-Length: 20 
Content-Type: text/html; charset=utf-8 
Date: Thu, 07 Dec 2017 00:17:08 GMT 
Keep-Alive: timeout=5, max=100 
Server: Apache/2.4.29 (Debian) 
Vary: Accept-Encoding 

あなたは、サーバーが言っていることがわかりますどのドメインも問題なく(*)、POSTはOKです。ただし、フォローアップPOSTはありません。私は何が欠けていますか?

ありがとうございました。

+1

''*''を ''http:// localhost''に変更し、エラーハンドラをajaxリクエストに追加してみてください。 – charlietfl

答えて

2

http://api.localhost/authまた、Access-Control-Allow-Headers: content-typeを送信する必要があります。

は、Apacheの設定にだから、あなたもこれを追加する必要があります。

あなたのフロントエンドコードの contentType: "application/json"一部が要求に Content-Type: application/jsonヘッダを追加するために必要なのです
Header always set Access-Control-Allow-Headers "content-type" 

、およびContent-Typeリクエストヘッダの任意の値text/plain,application/x-www-form-urlencoded、またはmultipart/form-data以外の場合、ブラウザはCORSプリフライトOPTIONSリクエストを送信します。あなたが持っている場合

は、だからあなたのhttp://api.localhost/authサーバーは、プリフライトを成功させ、そしてそのブラウザはフロントエンドのコードからPOST要求を行うに移動させなければならないAccess-Control-Allow-Headers: content-typeレスポンスヘッダを送り返します。

+0

すべてのリクエストに対してプリフライトを実行しているようです。それは要求の数を2倍にするでしょう。その周りには何か方法はありますか? – Dave

+1

Apacheサーバーは、応答のキャッシュをOPTIONSレスポンスにキャッシュするように指示するAccess Control-Max-Age 応答ヘッダーを送信するように設定することもできます。 https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age。しかし、おそらく600以上の値を設定したくないのではないでしょうか(10分)。もしそうならば、Chromeはそれを600にクランプします(つまり、ChromeではOPTIONSレスポンスは10分)。 – sideshowbarker

+0

ありがとう。 5秒でさえも巨大です。ページが最初に読み込まれたときに、私は10のメソッドを要求するとしましょう。それは20リクエストを生成することになりますが、5秒のキャッシュでさえ、これをノックダウンすると11になります。 – Dave

関連する問題