14

そのため、CORS を使用してサービスへの GET 呼び出しを正常に行うことができます。ただし、POST、PUT、および DELETE 操作のプリフライト レベルで何か問題が発生しているはずです。ただし、私が知る限り、サーバーが OPTIONS クエリに応答して返すヘッダー応答は正しく、で説明されているものと一致しています。

JQuery 1.6.4 で $.ajax を使用した私の JavaScript コードを次に示します。

$.ajax({
  url: 'http://myhome:8080/TaskApproval/resources/tasks/2',
  context: this,
  data: '<?xml version="1.0" encoding="UTF-8"?> <task> <description>Get carrots from the grocery store</description><originator>Chris</originator><subject>Get Carrots !!</subject><taskId>2</taskId> </task> ',
  timeout: 30000,
  type: 'PUT',
  contentType: 'application/xml',
  success: function(response) {
    alert(response);
    result = response;
  },
  error: function(xhr) {
    alert('Error!  Status = ' + xhr.status + " Message = " + xhr.statusText);
  }
});

これが、Firebug の好意による、私の HTTP トレイルの外観です。

リクエスト:

OPTIONS /TaskApproval/resources/tasks/2 HTTP/1.1
Host: widgethome:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:6.0.2) Gecko/20100101 Firefox/6.0.2
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
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Origin: http://localhost:8080
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: content-type

応答:

HTTP/1.1 200 OK
X-Powered-By: Servlet/3.0
Server: GlassFish v3
Allow: OPTIONS,GET,DELETE,HEAD,PUT, POST
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Max-Age: 1000
Access-Control-Allow-Headers: *
Content-Type: application/xml
Content-Length: 2792
Date: Wed, 28 Sep 2011 18:21:11 GMT

その場合、PUT (または POST または DELETE) はありません。次のような面倒で役に立たない xhr オブジェクトを取得するだけです。

readyState  0 
responseText    ""
status  0
statusText  "error"

その後、Ajax 呼び出しで contentType を削除し、アプリケーションごとに無効なコンテンツ タイプを送信すると、ブラウザーは実際に PUT 要求を送信しますが、Content-Type が application/xml ではないため失敗します。下記参照:

$.ajax({
  url: 'http://myhome:8080/TaskApproval/resources/tasks/2',
  data: '<?xml version="1.0" encoding="UTF-8"?> <task> <description>Get carrots from the grocery store</description><originator>Chris</originator><subject>Get Carrots !!</subject><taskId>2</taskId> </task> ',
  timeout: 30000,
  type: 'PUT',
  //contentType: 'application/xml',
  success: function(response) {
    alert(response);
    result = response;
  },
  error: function(xhr) {
    alert('Error!  Status = ' + xhr.status + " Message = " + xhr.statusText);
  }
});

これも Firebug の厚意により、この HTTP トレイルにつながります。

オプションのリクエスト:

OPTIONS /TaskApproval/resources/tasks/2 HTTP/1.1
Host: myhome:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:6.0.2) Gecko/20100101 Firefox/6.0.2
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
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Origin: http://localhost:8080
Access-Control-Request-Method: PUT

オプションの応答:

HTTP/1.1 200 OK
X-Powered-By: Servlet/3.0
Server: GlassFish v3
Allow: OPTIONS,GET,DELETE,HEAD,PUT, POST
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Max-Age: 1000
Access-Control-Allow-Headers: *
Content-Type: application/xml
Content-Length: 2792
Date: Wed, 28 Sep 2011 18:26:23 GMT

プットリクエスト:

PUT /TaskApproval/resources/tasks/2 HTTP/1.1
Host: myhome:8080
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:6.0.2) Gecko/20100101 Firefox/6.0.2
Accept: */*
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://localhost:8080/TaskApproval/crossdomain.html
Content-Length: 197
Origin: http://localhost:8080

プットレスポンス:

HTTP/1.1 415 Unsupported Media Type
X-Powered-By: Servlet/3.0
Server: GlassFish v3
Content-Type: text/html
Content-Length: 1069
Date: Wed, 28 Sep 2011 18:26:23 GMT

コンテンツ application/x-www-form-urlencoded はサポートせず、application/xml のみをサポートするため、415 は理にかなっています。私が理解できないのは、Content-Type を正しく設定すると PUT が妨げられるのはなぜですか?

洞察をありがとう!私はかなり長い間インターネットを検索してきましたが、この問題の解決策が見つかりません。

4

2 に答える 2

32

プリフライトと実際の応答の両方に CORS ヘッダーを含める必要があります。したがって、サーバーからの PUT 応答に次のヘッダーを含めてみてください。

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Headers: Content-Type

CORS 仕様には、Access-Control-Allow-Headers の有効な値として「*」がリストされていないことに注意してください。

http://www.w3.org/TR/cors/#access-control-allow-headers-response-he

代わりに、次のようにすべてのリクエスト ヘッダーを明示的にリストしてみてください。

Access-Control-Allow-Headers: Content-Type

値が application/x-www-form-urlencoded、multipart/form-data、または text/plain でない場合、Content-Type は単純なヘッダーと見なされないため、Content-Type を含める必要があります (詳細については、CORS 仕様を参照してください)。単純なヘッダーで)。

于 2011-09-29T14:51:13.837 に答える