AJAX GET
からhttp://qualifiedlocalhost:8888/resource.json
へのトリガー]は、予想されるCORSプリフライトを開始します。
OPTIONS
リクエストRequest URL:http://qualifiedlocalhost:8888/resource.json
Request Method:OPTIONS
Status Code:200 OK
リクエストヘッダー
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, Origin, x-requested-with
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
Host:qualifiedlocalhost:8888
Origin:http://localhost:9000
Pragma:no-cache
Referer:http://localhost:9000/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36
応答ヘッダー
Access-Control-Allow-Headers:Content-Type, X-Requested-With
Access-Control-Allow-Methods:GET,PUT,POST,DELETE
Access-Control-Allow-Origin:*
Connection:keep-alive
Content-Length:2
Content-Type:text/plain
Date:Thu, 01 Aug 2013 19:57:43 GMT
Set-Cookie:connect.sid=s%3AEpPytDm3Dk3H9V4J9y6_y-Nq.Rs572s475TpGhCP%2FK%2B2maKV6zYD%2FUg425zPDKHwoQ6s; Path=/; HttpOnly
X-Powered-By:Express
動作するはずですよね?
ただし、後続のリクエストは引き続きエラーXMLHttpRequest cannot load http://qualifiedlocalhost:8888/resource.json. Origin http://localhost:9000 is not allowed by Access-Control-Allow-Origin.
で失敗します
Request URL:http://qualifiedlocalhost:8888/resource.json
リクエストヘッダー
Accept:application/json, text/plain, */*
Cache-Control:no-cache
Origin:http://localhost:9000
Pragma:no-cache
Referer:http://localhost:9000/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36
X-Requested-With:XMLHttpRequest
多分それは私の目の前で見つめています。しかし、何かアイデアはありますか?念のため、AngularJS $resource
を使用して、CompoundJSサーバーと通信しています。
access-Control-Allow-Methodsを「GET、POST」から「GET、POST、PUT、DELETE」に変更します
前:
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization');
next();
});
後:
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT ,DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization');
next();
});
I 最近同じ問題がありました 。問題は、Access-Control-Allow-Origin
ヘッダー(使用する場合は、Access-Control-Allow-Credentials
ヘッダー)は、プリフライトレスポンスと実際のレスポンスの両方にで送信する必要があります。
あなたの例では、プリフライトレスポンスにのみ含まれています。
Webサーバー/取得機能もHTTPヘッダーAccess-Control-Allow-Originを含んでいますか?最終的に、AngularJS 1.0.7とリモートJavaサーブレットを使用して、その追加で成功しました。これは私のJavaコードスニペットです。AngularJSクライアントでの変更は不要です。
サーブレット:
@Override
protected void doOptions(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Send Response
super.doOptions(request, response);
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, X-Requested-With");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/* ... */
response.setHeader("Access-Control-Allow-Origin", "*");
}
よりエレガントな代替手段は、サーブレットフィルターです。
サーバーが正しいCORSヘッダーを送信している同じ問題に気付きましたが、ブラウザはCORS要件が満たされていないと判断するため失敗します。さらに興味深いことに、この場合、同じブラウザセッションでの一部のAJAX呼び出しでのみ発生しますが、すべてではありません。
ブラウザのキャッシュをクリアすると、この場合の問題が解決します-私の現在の理論では、これはクロスオリジンサーバーによって設定されたCookieと関係があるということです。シナリオでは、プリフライトOPTIONSリクエストへの応答の一部としてCookieが設定されていることに気付きました。別のオリジンからのリクエストに対して、そのサーバーでCookieを設定しないようにしましたか?
ただし、ブラウザをリセットすると問題が再発する場合があることに気付きました。また、ブラウザーをプライベートモードで実行すると、問題が解消され、ブラウザーのキャッシュにある問題に関連する問題が指摘されます。
参考のために、ここに私のシナリオがあります(私はこれをSOの新しい質問としてほぼ投稿しましたが、代わりにここに入れます)。
somejQuery.ajaxを介して行われたCORS GETリクエストが失敗するバグに遭遇しました。特定のブラウザセッションでは、プリフライトOPTIONSリクエストが通過し、その後に実際のリクエストが続きます。同じセッションで、一部のリクエストは通過し、他のリクエストは失敗します。
ブラウザネットワークコンソールでのリクエストとレスポンスのシーケンスは次のようになります。
まず、OPTIONSプリフライトリクエスト
OPTIONS /api/v1/users/337/statuses
HTTP/1.1 Host: api.obfuscatedserver.com
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://10.10.8.84:3003
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
Access-Control-Request-Headers: accept, Origin, x-csrf-token, auth
Accept: */* Referer: http://10.10.8.84:3003/
Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8
次のような応答があります。
HTTP/1.1 200 OK
Date: Tue, 06 Aug 2013 19:18:22 GMT
Server: Apache/2.2.22 (Ubuntu)
Access-Control-Allow-Origin: http://10.10.8.84:3003
Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT
Access-Control-Max-Age: 1728000
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: accept, Origin, x-csrf-token, auth
X-UA-Compatible: IE=Edge,chrome=1
Cache-Control: no-cache
X-Request-Id: 4429c4ea9ce12b6dcf364ac7f159c13c
X-Runtime: 0.001344
X-Rack-Cache: invalidate, pass
X-Powered-By: Phusion
Passenger 4.0.2
Status: 200 OK
Vary: Accept-Encoding
Content-Encoding: gzip
次に、実際のGETリクエスト、
GET https://api.obfuscatedserver.com/api/v1/users/337
HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
Referer: http://10.10.8.84:3003/
Origin: http://10.10.8.84:3003
X-CSRF-Token: xxxxxxx
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
auth: xxxxxxxxx
ブラウザコンソールでエラーが表示されるのは、
XMLHttpRequest
cannot load https://api.obfuscatedserver.com/api/v1/users/337.
Origin http://10.10.8.84:3003 is not allowed by Access-Control-Allow-Origin.
追加のデバッグ
Curlを使用して同じシーケンスを再生できますが、サーバーから有効な応答が返されます。つまり、要求を通過させるはずの予想されるCORSヘッダーがあります。
プライベート/シークレットブラウザウィンドウで同じシナリオを実行しても、問題は再現しませんでした。これにより、キャッシュをクリアしようとしたので、問題も解消されました。しかし、しばらくしてから戻ってきました。
この問題は、iPhoneサファリとOSXデスクトップのChromeで再現されていました。
私が本当に助けが必要なもの
クロスオリジンドメインに設定されたいくつかのCookieがここで関与し、潜在的にブラウザのバグを公開しているのではないかと考えています。これをさらに試行してデバッグするために、ブラウザー(ネイティブスタック)に設定できるツールまたはブレークポイントはありますか? CORSポリシーを評価するコード内のブレークポイントが理想的です。
corsモジュールを使用して問題を回避します
var cors = require('cors')
var app = express()
app.use(cors())
「オプション」への応答は正常に機能しているようです。問題は「get」応答にあるようです。
「get」応答で「options」応答と同じCORSヘッダーを返すようにする必要があります。
特に、「get」応答には
Access-Control-Allow-Headers:Content-Type, X-Requested-With
Access-Control-Allow-Methods:GET,PUT,POST,DELETE
Access-Control-Allow-Origin:*