5

私がやろうとしているのは、AJAX 呼び出しを同じ Web サーバーに送信するが HTTPS を使用する HTTP プロトコルのページを作成することです。要求ページと AJAX ハンドラーの両方が同じサーバー上にあり、同じドメインとポートを持っています。(つまり、唯一の違いはプロトコルです。) 説明するために、

http://www.example.com/index.phpから

https://www.example.com/authenticate.php?user=123&password=456への jQuery AJAX 呼び出しをトリガーし ます

(パスワードを HTTPS 経由で渡して、インターネット上で暗号化することを望んでいます。設計上の制約により、ページをリダイレクトする代わりに AJAX 呼び出しを使用する必要があります。)

ここに CORS の問題があることを理解しているので、少し調査したところ、Access-Control-Allow-Origin ヘッダーを実際に利用できることがわかりました。次に、Apache の構成ファイルに次のように設定します。

Header set Access-Control-Allow-Origin *
Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Header set Access-Control-Allow-Headers "content-type, accept"
Header set Access-Control-Max-Age 1000

ブラウザーがサーバーからリソースを要求すると、ヘッダーが表示されることがわかります。リクエスト:

Accept  */*
Accept-Encoding gzip, deflate
Accept-Language en-us,en;q=0.5
Authorization   Basic Y2FzZXRhZ3JhbWRldjpwYXNzd29yZGRldiE=
Cache-Control   no-cache
Connection  keep-alive
Cookie  __utma=99230732.2019724749.1337107099.1337849971.1337856946.9; __utmz=99230732.1337107099.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utma=217650581.954519005.1337107174.1337772401.1337777327.5; __utmz=217650581.1337107174.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmc=99230732; PHPSESSID=m8lnqhqv2qa6f884a8um413n81
Host    www.example.com
Pragma  no-cache
Referer http://www.example.com/index.php
User-Agent  Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:12.0) Gecko/20100101 Firefox/12.0

応答は次のようになります。

Accept-Ranges   bytes
Access-Control-Allow-Head...    content-type, accept
Access-Control-Allow-Meth...    GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Orig...    *
Access-Control-Max-Age  1000
Connection  close
Content-Length  16599
Content-Type    application/x-javascript
Date    Thu, 24 May 2012 14:48:17 GMT
Etag    "48157-40d7-4c0c938b220c0"
Last-Modified   Thu, 24 May 2012 14:39:39 GMT
Server  Apache/2.2.3 (CentOS)

ということで、ヘッダー部分は満たされているようです。(私は正しいですか?)

次に、JavaScriptで次のjQuery AJAXコードを呼び出そうとしたとき、

$.ajax({
    // Use HTTPS as there is password transferred
  url : "https://www.example.com/authentication.php",
  type : 'POST',
  dataType : 'json',
  async : false,
  data : ajaxData,
  beforeSend : function(xhr, opt) {},
  error : function(error) {
    console.log("Ajax error: unable to login user: ");
    console.log(error);
  },
  success : function(status) {
    if(status==USER_AUTH_AUTHENTICATE_USER_SUCCESS) {
      console.log("User login succeeded!");
    } else {
      console.log("User login failed.");
    }
  }
});

ブラウザ (FireFox 12) はオブジェクトを返すだけで、

readyState 0
status 0
statusText "[Exception... "Access to restricted URI denied" code: "1012" nsresult: "0x805303f4 (NS_ERROR_DOM_BAD_URI)" location: "http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js Line: 8240"]"

見逃したものはありますか?

実際、私はフォーラムやブログから多くの提案を試みましたが、それでもうまくいきませんでした。JSONP も使用してみましたが、FireFox では正常に動作しますが、Chrome/Safari では読み取りエラー メッセージが表示されずに失敗しましたが、jQuery コード "head.insertBefore( script, head.firstChild );" からエラーがスローされました。

私のコード/設定のどこが悪いのか、誰かが私に手がかりを与えることができれば、大いに感謝します。

ありがとう!

2012-05-25 20:29 (UTC +08:00) に編集

示唆されているように、この参照ケース (http://stackoverflow.com/questions/5750696/how-to-get-a-cross-origin-resource-sharing-cors-post-request-working) を読んだところ、リンクしていることがわかりましたこの場合(http://stackoverflow.com/questions/5584923/a-cors-post-request-works-from-plain-javascript-but-why-not-with-jquery)にも関連しています。そこでサンプルのXHRコードを試してみたところ、

var request = new XMLHttpRequest();
var params = "action=something";
request.open('POST', 'https://www.example.com/controllers/Authentication.php', true);
request.onreadystatechange = function() {if (request.readyState==4) alert("It worked!");};
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.setRequestHeader("Content-length", params.length);
request.setRequestHeader("Connection", "close");
request.send(params);

コードは、HTTP プロトコルを使用してページから呼び出されます。コードが実行されると、すぐに以下のエラーがスローされます。

制限された URI へのアクセスが拒否されました...test_xhr.php 11 行目

(JavaScript HTTP で HTTPS を変更すると、スクリプトはすぐに動作するため、構文の問題などは発生しないはずです。)

ページ自体のリクエスト ヘッダーとレスポンス ヘッダーは次のとおりです。リクエストは、

Accept  text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-us,en;q=0.5
Authorization   Basic Y2FzZXRhZ3JhbWRldjpwYXNzd29yZGRldiE=
Cache-Control   no-cache
Connection  keep-alive
Cookie  __utma=99230732.2019724749.1337107099.1337856946.1337921578.10; __utmz=99230732.1337107099.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utma=217650581.954519005.1337107174.1337772401.1337777327.5; __utmz=217650581.1337107174.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); __utmc=99230732; PHPSESSID=ktd6anojfi40ohemlujosdmhi4
Host    www.example.com
Pragma  no-cache
User-Agent  Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:12.0) Gecko/20100101 Firefox/12.0

応答は、

Access-Control-Allow-Head...    content-type, accept
Access-Control-Allow-Meth...    GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Orig...    *
Access-Control-Max-Age  1000
Connection  close
Content-Length  590
Content-Type    text/html; charset=UTF-8
Date    Fri, 25 May 2012 12:24:44 GMT
Server  Apache/2.2.3 (CentOS)
X-Powered-By    PHP/5.1.6

したがって、ネイティブ XHR も機能しないため、jQuery ではなく、セットアップに根本的な問題があると考えているだけです。:(

4

1 に答える 1

1

2 つの問題があります。

1) Access-Control-Allow-Origin "*" は認証された呼び出しでは機能しません。代わりに * 呼び出し Access-Control-Request-Origin または Origin ヘッダー フィールドを反映します。

2) レスポンスに Access-Control-Allow-Credentials: true が必要です。

役立つ可能性のあるその他のこと: 認証ヘッダーを手動で設定する、base64 で名前とパスワードを組み立てる。これが最も確実に機能する方法です。その利点は欠点です。Authorization ヘッダーを手動で設定すると、OPTIONS ヘッダー ベースの CORS ハンドシェイクが有効になります。(すべてのリクエストの前に、処理する必要がある OPTIONS リクエストがあります)これは、最新のすべてのブラウザで一貫した実装をしているようです(もちろんIE9は例外ですが、IE10は動作すると言われています)。

HTH

于 2012-09-08T01:36:22.600 に答える