[解決済み] 安全でないレスポンスや接続拒否によりajaxコールが失敗したかどうかを判断する
質問
いろいろと調べてみたのですが、これを処理する方法が見つかりませんでした。私はhttpsサーバーからjettyを実行しているlocahost httpsサーバーへのjQuery ajaxコールをカスタム自己署名証明書で実行しようとしています。私の問題は、応答が接続拒否または安全でない応答(証明書の受け入れがないため)であるかどうかを判断できないことです。両方のシナリオの違いを判断する方法はありますか?その
responseText
と
statusCode
は、クロームコンソールでは違いが見えるのに、どちらも常に同じです。
net::ERR_INSECURE_RESPONSE
net::ERR_CONNECTION_REFUSED
responseText
は常に ""であり
statusCode
は常に "0"となります。
私の質問は、jQueryのajaxコールが、以下の理由で失敗したかどうかを判断する方法です。
ERR_INSECURE_RESPONSE
が原因なのか
ERR_CONNECTION_REFUSED
?
証明書が承認されると、すべてがうまく機能しますが、ローカルホスト サーバーがシャットダウンされているのか、それとも稼働しているが証明書がまだ承認されていないのかを知りたいのです。
$.ajax({
type: 'GET',
url: "https://localhost/custom/server/",
dataType: "json",
async: true,
success: function (response) {
//do something
},
error: function (xhr, textStatus, errorThrown) {
console.log(xhr, textStatus, errorThrown); //always the same for refused and insecure responses.
}
});
<イグ
手動でリクエストを行っても、同じ結果になります。
var request = new XMLHttpRequest();
request.open('GET', "https://localhost/custom/server/", true);
request.onload = function () {
console.log(request.responseText);
};
request.onerror = function () {
console.log(request.responseText);
};
request.send();
どのように解決するのですか?
最新の Web ブラウザと区別する方法がありません。
W3Cの仕様です。
以下のステップは、単純なクロスオリジンリクエストのために、ユーザエージェントが何をしなければならないかを記述しています。 :
リクエストの作成手順を適用し、リクエストの作成中に以下のリクエストルールを守ってください。
手動リダイレクトフラグが設定されておらず、レスポンスのHTTPステータスコードが301、302、303、307、または308である場合 リダイレクトの手順を適用してください。
エンドユーザがリクエストをキャンセルした場合 中止のステップを適用します。
ネットワークエラーが発生した場合 DNSエラーやTLSネゴシエーション失敗など、ネットワークエラーが発生した場合は、以下のように ネットワークエラーの手順 . エンドユーザーとの対話は一切要求しないでください。
注意: HTTP ステータスコード 410 のような、何らかのエラーを示す HTTP レスポンスは含まれません。
その他 リソース共有チェックを行う。失敗を返した場合は、ネットワークエラーの手順を適用する。それ以外の場合、pass を返したら、このアルゴリズムを終了して cross-origin リクエストのステータスを success に設定する。実際にはリクエストを終了させないでください。
読んで字の如く、ネットワークエラーはエラーを含むHTTPレスポンスを含まないため、ステータスコードは常に0、エラーは""となります。
注意 : 以下の例は、Google Chrome バージョン 43.0.2357.130 を使用し、OP1をエミュレートするために作成した環境に対して作成したものです。セットアップのためのコードは回答の最下部にあります。
私は、これを回避するためのアプローチは、HTTPSの代わりにHTTPでセカンダリリクエストを作成することであると思いました。 この回答は を使用することですが、新しいバージョンのブラウザは混合コンテンツをブロックするため、それは不可能であると記憶しています。
つまり、Web ブラウザは、HTTPS を使用している場合は HTTP でのリクエストを許可せず、その逆もまた然りということです。
これは数年前からのことですが、Mozilla Firefox のバージョン 23 より下のような古い Web ブラウザでは、これを許可しています。
それについての証拠。
Web Broserコンソールを使用してHTTPSからHTTPリクエストを行う。
var request = new XMLHttpRequest();
request.open('GET', "http://localhost:8001", true);
request.onload = function () {
console.log(request.responseText);
};
request.onerror = function () {
console.log(request.responseText);
};
request.send();
を実行すると、次のようなエラーが発生します。
ミックスコンテンツです。のページは、' https://localhost:8000/ ' のページは HTTPS で読み込まれましたが、安全でない XMLHttpRequest のエンドポイントである ' http://localhost:8001/ '. このリクエストはブロックされました。コンテンツは HTTPS で提供する必要があります。
Iframeを追加するなどの他の方法でこれを実行しようとすると、ブラウザのコンソールに同じエラーが表示されます。
<iframe src="http://localhost:8001"></iframe>
ソケット接続を使用することも 回答として投稿 ということで、同じような結果になることは間違いないのですが、一応試してみました。
HTTPS を使用して Web Broswer から非セキュア ソケット エンドポイントにソケット接続を開こうとすると、ミックス コンテンツ エラーで終わります。
new WebSocket("ws://localhost:8001", "protocolOne");
1) 混在するコンテンツ のページは https://localhost:8000/ のページは HTTPS で読み込まれましたが、安全でない WebSocket エンドポイント 'ws://localhost:8001/' に接続しようとしました。このエンドポイントは WSS 上で利用可能である必要があります。
2) キャッチされない DOMException。WebSocket'の構築に失敗しました。安全でないWebSocket接続は、HTTPSで読み込まれたページから開始されないかもしれません。
それから、私はネットワーク接続エラーに関するいくつかの情報を読むことができるかどうかを確認するために、wssエンドポイントに接続しようとしました。
var exampleSocket = new WebSocket("wss://localhost:8001", "protocolOne");
exampleSocket.onerror = function(e) {
console.log(e);
}
上記のスニペットをServerをOFFにして実行した結果。
wss://localhost:8001/' への WebSocket 接続に失敗しました。接続の確立でエラーが発生しました: net::ERR_CONNECTION_REFUSED
サーバーをOnにして上記のスニペットを実行する
<ブロッククオートwss://localhost:8001/' への WebSocket 接続に失敗しました。WebSocketのオープニングハンドシェイクがキャンセルされました。
しかし、再度、"onerror function"がコンソールに出力するエラーは、他のエラーと区別するためのヒントがありません。
プロキシを使用して この回答では は動作しますが、ターゲットサーバがパブリックアクセスである場合のみです。
これはこのケースではないので、このシナリオでプロキシを実装しようとすると、私たちは同じ問題に直面することになります。
Node.jsのHTTPSサーバを作成するコード :
自己署名証明書を使用する2つのNodejs HTTPSサーバを作成しました。
targetServer.js。
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('./certs2/key.pem'),
cert: fs.readFileSync('./certs2/key-cert.pem')
};
https.createServer(options, function (req, res) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.writeHead(200);
res.end("hello world\n");
}).listen(8001);
applicationServer.jsを使用します。
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('./certs/key.pem'),
cert: fs.readFileSync('./certs/key-cert.pem')
};
https.createServer(options, function (req, res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(8000);
これを動作させるには、Nodejsをインストールし、各サーバーごとに別々の証明書を生成し、それに応じてcertsとcerts2フォルダに格納する必要があります。
実行するには、以下のコマンドを実行するだけです。
node applicationServer.js
と
node targetServer.js
をターミナルで表示します(ubuntuの例)。
関連
-
[解決済み] jQuery Ajax呼び出し後のリダイレクトリクエストを管理する方法
-
[解決済み] 配列からオブジェクトを生成する
-
[解決済み] チェックボックスが選択されているかどうかを確認するjQuery
-
[解決済み] 文字列のn番目の出現箇所を取得するには?
-
[解決済み] 文字列がhtmlであるかどうかをチェックする
-
[解決済み] 無効になっている入力フィールドの値を送信する
-
[解決済み] jQueryの$という記号の意味は何ですか?
-
[解決済み] Chromeの拡張機能開発にWebStormを使用するにはどうすればよいですか?
-
[解決済み] 各オブジェクトに?重複
-
[解決済み] JavaScriptとLuaの微妙な違い [終了しました]
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] TypeScriptのdeclare classとinterfaceの違いとは?
-
[解決済み] JavaScriptのtoString()関数をオーバーライドして、デバッグ用に意味のある出力を提供することは可能でしょうか?
-
[解決済み] react-routerのハッシュフラグメントからクエリパラメータを取得する
-
[解決済み] JavaScript のオブジェクトの配列を比較し、最小値/最大値を取得する
-
[解決済み] jQueryで入力ファイルが空かどうかをチェックする方法
-
[解決済み] Promise : then vs then + catch [重複].
-
[解決済み] 文字列とラベルのローカライズとグローバリゼーションのベストプラクティス【終了しました
-
[解決済み] Prototypeを使ってtextareaを自動サイズ調整するには?
-
[解決済み] JavaScriptとLuaの微妙な違い [終了しました]
-
[解決済み] JavaScriptの文字列プリミティブとStringオブジェクトの違いは何ですか?