汎用ドメイン間リソースリクエスト分析


WEB開発の過程で最もよく使われるAjax技術はクライアントとサーバーの通信を完成させる.一方、Ajax通信を実現するXmlHttpRequestオブジェクトは、ドメイン間セキュリティポリシーの問題をもたらします.簡単に言えば、デフォルトでは、XHRオブジェクトは、それを含むページと同じドメインにあるリソースにのみアクセスできます.
では、問題が発生しました.ドメインをまたぐのは何ですか.通常、Ajaxが指すアドレスでは、2次ドメイン名/ポート番号/プロトコル/は、それを含むページと同じでなければなりません.栗を挙げます.
     www.tangide.comアクセスwww.i 5 r.comはドメイン間です.    a.tangide.comアクセスb.tangide.comはドメイン間です.    www.tangide.com:8080 www.tangide.com:8090はドメイン間です.    http://www.tangide.comアクセスhttps://www.tangide.comドメイン間です.
ドメイン間ではセキュリティ上の問題が発生しますが、ドメイン間でリソースを要求する必要がある場合があります.次に、2つの一般的なドメイン間メソッドについて説明します.
1)CORS:ドメイン間資源共有と略称する
大まかな動作原理は、A上のページがB上のリソースを取得しようとしている場合、ブラウザはまずHEAD要求を送信してBサーバのhttpヘッダを取得し、Access-Control-Allow-OriginがAを持っているかどうかを判断する(以前の栗の推測による)ブラウザはドメインを越えて許可し、そうでなければ拒否する~
テストコードを簡単に書き、Nodejsで簡単なサーバを構築します.
	var http = require('http');

	var server = http.createServer(function(req, res) {
     		res.writeHead(200, {'Content-Type':'text/plain',
                         'Access-Control-Allow-Origin':'http://www.i5r.com',
                         'Access-Control-Allow-Headers':'If-Modified-Since'})    ;
		console.log((req.url));
		console.log((req.headers));
		res.end(JSON.stringify({code: 0, message:'ok'}));
	});
 
	server.listen(8090);
 
サーバは8090ポートをリスニングします.Access-Control-Allow-Originオプションには、サーバがドメイン間リソースリクエストを許可するoriginがリストされます.Access-Control-Allow-Headersオプションは、クライアントが送信できるヘッダ情報を構成するために使用されます.If-Modified-Sinceオプションは、主にブラウザのキャッシュに使用されます.ブラウザがhttpリクエストを送信してリソースを取得すると、If-MOdified-Sinceオプションにリソースファイルが最後に変更された時間(GMT形式)が付き、この時点以降リクエストされたリソースが変更された場合にリソースが更新されることを示します.そうでない場合、サーバは「Not Modified」を示す304ステータスコードを返す.したがって、ブラウザがキャッシュしないように強制するリソースがある場合は、If-Modified-Sinceを0に設定して、サーバからリソースを毎回取得することができます.
次に、クライアントテストコードを作成します.
<!DOCTYPE html>
<html>
<head>
	<meta http-equiv='Content-Type' Content='type=text/html;chatset=utf-8'>
	<script type='text/javascript' src='ajax.js'></script>
	<script type="text/javascript">
		window.onload = function() {
			var button = document.createElement('input');	
			button.setAttribute('type', 'button');
			button.setAttribute('value', 'send request');
			document.getElementsByTagName('body')[0].appendChild(button);
			button.onclick = function() {
				window.handle = Ajax.getInstance();
				handle.testAction('/read.php', function(result) {
					console.log(JSON.stringify(result));
				});
			};
		};		
	</script>
</head>
<body>
</body>
</html>
Ajax要求の関連コードを送信する:
funcntion testAction(action, onDone) {
		var info = {};
		info.method = 'post';
		info.url = 'http://www.i5r.com:8090' + action;
		httpSendRequest(info);
	}
     function httpSendRequest(info) {
	var xhr = new window.XMLHttpRequest();

	if(!info || !info.url) {
		return false;
	}

	var url = info.url;
	var data= info.data;
	var method = info.method ? info.method : "GET";

	xhr.open(method, url, true);
	xhr.send(info.data ? info.data : null);
	xhr.onreadystatechange = function() {
		if(info.onProgress) {
			info.onProgress(xhr);	
		}	
		if(xhr.readyState === 4) {
			if(info.onDone) {
				info.onDone(true, xhr, xhr.responseText);
				console.log("response:" + xhr.responseText);
			}
		}
		console.log("onreadystatechange:" + xhr.readyState);
		return;
	};
	
サーバは8090ポートを傍受しているが、www.i 5 r.comはドメイン間許可リストに追加されているので、通常は次のように出力されます.
response:{"code":0,"message":"ok"}
onreadystatechange:4 
「Access-Control-Allow-Origin」:'http://www.i5r.comデフォルトで8080ポートをサポートするドメイン間リクエスト:'Access-Control-Allow-Origin':'http://www.i5r.com'.ページの更新:送信要求をクリックすると、次のエラーメッセージが表示されます.
    
XMLHttpRequest cannot load http://www.i5r.com:8090/read.php. The 'Access-Control-Allow-Origin' header has a value 'http://www.i5r.com:8080' that is not equal to the supplied origin. Origin 'http://www.i5r.com' is therefore not allowed access.
エラーメッセージが原因を説明しました~
expressで構築されたサーバの場合は、次のように構成できます.
	app.use(function(req, res, next) {
	  res.header("Access-Control-Allow-Origin", "*");
	  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
	  next();
	});
ここで「*」はワイルドカードであり、したがって要求ソースがドメインにまたがることを許可することを示す.
2)JSONPを使用してドメイン間リソース要求を完了し、まずフロントエンドテストコードを作成する.
<html>
<head>
	<meta http-equiv='Content-Type' Content='type=text/html;chatset=utf-8'>
	<script type='text/javascript' src='ajax.js'></script>
	<script type="text/javascript">
		function handleResponse(res) {
			console.log(res);				
		}

		window.onload = function() {
			var button = document.createElement('input');	
			button.setAttribute('type', 'button');
			button.setAttribute('value', 'send request');
			document.getElementsByTagName('body')[0].appendChild(button);
			button.onclick = function() {
				var script = document.createElement('script');
				script.src = 'http://www.i5r.com:8090?callback=handleResponse';
				document.body.insertBefore(script, document.body.firstChild);
			};
		};		
	</script>
</head>
<body>
</body>
</html>
処理関数は、サーバ応答を受信した後、フィードバック情報を直接印刷する.
サーバのテストコードを変更するには、次の手順に従います.
var http = require('http');
var urlParser = require('url');

var server = http.createServer(function(req, res) {
	res.writeHead(200, {'Content-Type':'text/plain'});

	console.log(req.url);
	var query = urlParser.parse(req.url, true).query;
	console.log(query);
	if(query.callback) {
		var str = query.callback + "(" +JSON.stringify({code: 0, message:'ok'})+");";
		console.log(str);
		res.end(str);	
	}
	else {
		res.end(JSON.stringify({code: 0, message:'ok'}));
	}
});

server.listen(8090);
フロントエンドは、リクエストを送信するときにurlの後に「コールバック」関数の名前を追加し、サーバはリクエストを処理するときにコールバック関数を実行する必要があるデータフォーマットを直接返し、ブラウザが現在のページに同名の関数があると判断したときに実行する.これにより、ドメイン間リクエストが完了します.
最後に説明する必要があるのは、ドメイン間でブラウザの動作を制限することであり、JSやDOMの動作ではなく、自分でブラウザを開発してドメイン間でのサポートを完了する能力がある場合です:).
ドメインをまたいで要求するのはそれぞれメリットとデメリットがあります.もしあなたも似たような問題を研究しているなら、交流を歓迎します.
参考資料:https://github.com/drawapp8/gamebuilder/wiki/%E4%B8%AD%E6%96%87%E6%96%87%E6%A1%A3