ドメイン間要求の3つの処理方法JSONP、エージェント、CROS
23494 ワード
ドメイン別要求
シーン:ドメイン横断要求エラー:
Failed to loadhttp://localhost:3000/crossdomain/cors: No‘Access-Coontrol-Origin’header is present on the requested reource.Origin‘null’is therefore not allowed access. json cos cross crings sharring サーバエージェント 1.JSONP:
ドメインを横断すると、JSONPに話をしなければなりません.JSONPは「JSON with padding」と呼ばれています.古いバージョンのブラウザのクロスドメインデータアクセス問題を解決するために使えます.
ウェブページでjsファイルを呼び出しても、ブラウザのソースポリシーに影響されないので、scriptタグを通じてドメイン間要求ができます.は、まず、フロントエンドに、コールバック関数を設定し、urlのパラメータとして使用する必要があります. サービス端末は要求を受信した後、このパラメータを通してコールバック関数名を取得し、パラメータにデータを入れて に戻ります.結果を受け取ったらscriptタグですので、ブラウザはスクリプトとして動作し、ドメインをまたいでデータを取得する目的で になります.
jsonpがドメインをまたぐことができるのは、JSスクリプトのページ呼び出しが同ソースポリシーの影響を受けず、バックエンドにhttp要求を開始し、バックエンドに関数名を約束し、バックエンドに関数名を取得し、リターン結果を動的に計算し、バックエンドにJSスクリプトを実行することに相当する.
次に私たちは一例を通して試します.
バックエンドロジック:
スクリプトコマンドが使えるのは、package.jsonにスクリプトコマンドを設定したからです.
利点:は、XMLtpRequestオブジェクトがAjax要求を実現するように、同ソースポリシーに制限されている とは異なります.は相性がいいです.古いブラウザでもいいです. はXMLtpRequestまたはActiveXのサポートを必要としません.また、要求が完了したら、calbackを呼び出して結果を返送することができます. 短所:は、POSTなどの他のクラスのHTTP要求をサポートしないGET要求をサポートする. は、ドメインをまたぐHTTP要求だけをサポートしており、異なるドメインの2つのページまたはiframe間でデータ通信を行うことができない問題 を解決することができない. Jsonp要求がキャプチャできない場合の接続異常は、タイムアウトによる処理のみ可能です.
拡张:Jsonpの误区について ダイナミック要求はドメインをまたぐ問題があります.ドメインをまたぐのはブラウザの端だけです.Android/ios/Node.js/python/javaなどの他の環境にはありません. ドメインをまたぐと要求が送れなくなります.ドメインをまたぐ要求は送信できます.そして、サービス端末は要求を受信して結果を返すことができます.結果はブラウザによって阻止されました. 2.CORS:
CORSはW 3 C規格であり、全称は「ドメインをまたぐ資源共有」(Cross-orign resource shring)と呼ばれています.これにより、ブラウザがソースサーバにクロスして、XMLtpRequest要求を発行し、ajaxが同じソースでしか使用できない制限を克服しました.
CORSは、ブラウザとサーバーが同時にサポートされてこそ、有効になります.開発者にとって、CORS通信は同源のajax通信と同じです.コードは全く同じです.ブラウザは、ajaxがソースをまたぐことを要求すると、自動的にいくつかの付加的なヘッダ情報を追加し、時には追加の要求を出すことがありますが、ユーザーは感じていません.
したがって、CORS通信を実現する鍵はサーバである.サーバーがCORSインターフェースを実現すれば、ドメインを越えて通信することができます.
フロントエンドロジックは簡単です.正常にajax要求を開始すればいいです.
CORSの長所と短所:使用が簡単で、より安全です. は、POST要求方式 をサポートする. CORSは、新たなクロスドメイン問題の解決策であり、互換性のある問題があり、IE 10以上の をサポートするだけである.
拡張CORS:予備検査要求
CORSは要求を二つに分けて、一つは簡単な要求で、もう一つは複雑な要求(予備検査要求をトリガする必要がある)です.この二つは相対的で、どうやって「簡単ではない」と言えますか?下のいずれかに属するなら、簡単な要求ではない.
(1)PUT/DELETEなど、GET/POST/HEAD以外の要求方式を使用しています.
(2)Connect-Type/Acceptなどのいくつかの常用httpヘッダを使用しています.
事前点検はOPTTIONS方式で現在の要求が安全かどうかを確認してください.以下のようにお願いします.
フル
204
xhr
フル
200
xhr
サービスエンドのレスポンスは以下の通りです.
Access-Coontrol-Allow-Headers
DNT,X-CoustomHeader,Keep-Alive,User-Agent,X-requested-With,If-Maodified-Since,Cache-Control,Contee-Type,body
許可された要求ヘッダ
Access-Coontrol-Alllow-Mottehods
GET、POST、OPTONS、PUT、DELETE、PATCH
許可された要求方式
Access-Coontrol-Alllow-Myx-Age
17280000
事前点検要求有効期間:OPTIONS送信の時間間隔
もし事前検査要求で現在の要求がサービス側の設定に合致していないことを検出したら、直接に異常を投げないようにします.この時は「複雑」の要求を送る必要がありません.
CORSをサポートするために、nginxはこのように配合することができます.
サーバーエージェントは、ドメインをまたぐ要求操作が必要な場合はバックエンドに要求を送り、バックエンドが要求を代行してくれます.そして最後に取得した結果をあなたに送ります.
もしこのようなシーンがあるとしたら、あなたのページはCNode:Node.js専門中国語コミュニティのフォーラムを通じていくつかのデータを取得する必要があります.https://cnodejs.org/api/v1/topicsは、異なるドメインのため、バックエンドを要求し、その要求を転送の代わりにすることができます.
コードは以下の通りです
問題を残す: cookie tokenの具体的な用途 ネットワークセキュリティ クロスドメインネットワーク攻撃.
シーン:ドメイン横断要求エラー:
Failed to loadhttp://localhost:3000/crossdomain/cors: No‘Access-Coontrol-Origin’header is present on the requested reource.Origin‘null’is therefore not allowed access.
ドメインを横断すると、JSONPに話をしなければなりません.JSONPは「JSON with padding」と呼ばれています.古いバージョンのブラウザのクロスドメインデータアクセス問題を解決するために使えます.
ウェブページでjsファイルを呼び出しても、ブラウザのソースポリシーに影響されないので、scriptタグを通じてドメイン間要求ができます.
jsonpがドメインをまたぐことができるのは、JSスクリプトのページ呼び出しが同ソースポリシーの影響を受けず、バックエンドにhttp要求を開始し、バックエンドに関数名を約束し、バックエンドに関数名を取得し、リターン結果を動的に計算し、バックエンドにJSスクリプトを実行することに相当する.
次に私たちは一例を通して試します.
バックエンドロジック:
// jsonp/server.js
const url = require("url");
require("http")
.createServer((req, res) => {
const data = {
x: 10
};
//
const callback = url.parse(req.url, true).query.callback;
console.log(callback);
res.writeHead(200);
res.end(`${callback}(${JSON.stringify(data)})`);
})
.listen(3000, "127.0.0.1");
console.log(" , 127.0.0.1:3000");
先端ロジック:// jsonp/index.html
<script>
function jsonpCallback(data) {
alert(' X :' + data.x);
}
</script>
<script src="http://127.0.0.1:3000?callback=jsonpCallback"></script>
そして端末でサービスを開始します.スクリプトコマンドが使えるのは、package.jsonにスクリプトコマンドを設定したからです.
{
// yarn jsonp "node ./jsonp/server.js & http-server ./jsonp"
"scripts": {
"jsonp": "node ./jsonp/server.js & http-server ./jsonp",
"cors": "node ./cors/server.js & http-server ./cors",
"proxy": "node ./serverProxy/server.js",
"hash": "http-server ./hash/client/ -p 8080 & http-server ./hash/server/ -p 8081",
"name": "http-server ./name/client/ -p 8080 & http-server ./name/server/ -p 8081",
"postMessage": "http-server ./postMessage/client/ -p 8080 & http-server ./postMessage/server/ -p 8081",
"domain": "http-server ./domain/client/ -p 8080 & http-server ./domain/server/ -p 8081"
},
// ...
}
yarn jsonp
// 3000 8080
// localhost:3000 , 10
これで、JSONPを通じてドメインをまたいでデータを取得することに成功しましたが、このような方法によって、一定の長所と短所があります.利点:
拡张:Jsonpの误区について
CORSはW 3 C規格であり、全称は「ドメインをまたぐ資源共有」(Cross-orign resource shring)と呼ばれています.これにより、ブラウザがソースサーバにクロスして、XMLtpRequest要求を発行し、ajaxが同じソースでしか使用できない制限を克服しました.
CORSは、ブラウザとサーバーが同時にサポートされてこそ、有効になります.開発者にとって、CORS通信は同源のajax通信と同じです.コードは全く同じです.ブラウザは、ajaxがソースをまたぐことを要求すると、自動的にいくつかの付加的なヘッダ情報を追加し、時には追加の要求を出すことがありますが、ユーザーは感じていません.
したがって、CORS通信を実現する鍵はサーバである.サーバーがCORSインターフェースを実現すれば、ドメインを越えて通信することができます.
フロントエンドロジックは簡単です.正常にajax要求を開始すればいいです.
// cors/index.html
<script>
const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://127.0.0.1:3000', true);
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 && xhr.status === 200) {
alert(xhr.responseText);
}
}
xhr.send(null);
</script>
これは一回の正常な非同期ajax要求と何の区別もないようです.肝心なのはサービス側で要求を受けた後の処理です.// cors/server.js
require("http")
.createServer((req, res) => {
res.writeHead(200, {
"Access-Control-Allow-Origin": "http://localhost:8080",
"Content-Type": "text/html;charset=utf-8"
});
res.end(" :1111");
})
.listen(3000, "127.0.0.1");
console.log(" , 127.0.0.1:3000");
成功の鍵はAccess-Coontrol-Allow-Originが要求ページのドメイン名を含んでいるかどうかです.含まれていない場合、ブラウザはこれは失敗した非同期要求だと思います.xhr.onerrorの関数を呼び出します.CORSの長所と短所:
拡張CORS:予備検査要求
CORSは要求を二つに分けて、一つは簡単な要求で、もう一つは複雑な要求(予備検査要求をトリガする必要がある)です.この二つは相対的で、どうやって「簡単ではない」と言えますか?下のいずれかに属するなら、簡単な要求ではない.
(1)PUT/DELETEなど、GET/POST/HEAD以外の要求方式を使用しています.
(2)Connect-Type/Acceptなどのいくつかの常用httpヘッダを使用しています.
事前点検はOPTTIONS方式で現在の要求が安全かどうかを確認してください.以下のようにお願いします.
フル
204
xhr
フル
200
xhr
サービスエンドのレスポンスは以下の通りです.
Access-Coontrol-Allow-Headers
DNT,X-CoustomHeader,Keep-Alive,User-Agent,X-requested-With,If-Maodified-Since,Cache-Control,Contee-Type,body
許可された要求ヘッダ
Access-Coontrol-Alllow-Mottehods
GET、POST、OPTONS、PUT、DELETE、PATCH
許可された要求方式
Access-Coontrol-Alllow-Myx-Age
17280000
事前点検要求有効期間:OPTIONS送信の時間間隔
もし事前検査要求で現在の要求がサービス側の設定に合致していないことを検出したら、直接に異常を投げないようにします.この時は「複雑」の要求を送る必要がありません.
CORSをサポートするために、nginxはこのように配合することができます.
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
}
3.サービスエージェント:サーバーエージェントは、ドメインをまたぐ要求操作が必要な場合はバックエンドに要求を送り、バックエンドが要求を代行してくれます.そして最後に取得した結果をあなたに送ります.
もしこのようなシーンがあるとしたら、あなたのページはCNode:Node.js専門中国語コミュニティのフォーラムを通じていくつかのデータを取得する必要があります.https://cnodejs.org/api/v1/topicsは、異なるドメインのため、バックエンドを要求し、その要求を転送の代わりにすることができます.
コードは以下の通りです
// serverProxy/server.js
const url = require("url");
const http = require("http");
const https = require("https");
const server = http
.createServer((req, res) => {
const path = url.parse(req.url).path.slice(1);
if (path === "topics") {
https.get("https://cnodejs.org/api/v1/topics", resp => {
let data = "";
resp.on("data", chunk => {
data += chunk;
});
resp.on("end", () => {
res.writeHead(200, {
"Content-Type": "application/json; charset=utf-8"
});
res.end(data);
});
});
}
})
.listen(3000, "127.0.0.1");
console.log(" , 127.0.0.1:3000");
コードで確認できます.http://127.0.0.1:3000/topics サーバーが要求を受けたら、代わりに要請を送ります.https://cnodejs.org/api/v1/topics 最後に取得したデータをブラウザに送信します.問題を残す: