ホームページ  >  記事  >  ウェブフロントエンド  >  Ajaxのクロスドメイン問題を解決する方法

Ajaxのクロスドメイン問題を解決する方法

coldplay.xixi
coldplay.xixiオリジナル
2020-10-29 09:25:272240ブラウズ

Ajax クロスドメイン問題の解決策: 1. アクセスを許可するためにヘッダーを応答ヘッダーに追加します; 2. jsonp は get リクエストのみをサポートしますが、post リクエストはサポートしません; 3. httpClient 内部転送; 4. nginx を使用してビルドしますエンタープライズレベルのインターフェイスゲートウェイウェイ。

Ajaxのクロスドメイン問題を解決する方法

関連する無料学習の推奨事項: ajax (ビデオ)

Ajax クロスドメイン問題の解決策:

解決策 1: ヘッダーを応答ヘッダーに追加してアクセスを許可します

Cross-Origin Resource Sharing (CORS) Cross-Origin Resource Sharing

このクロスドメイン アクセス ソリューションのセキュリティ基盤は、「JavaScript はこの HTTP ヘッダーを制御できない」に基づいています

対象ドメインから返されるHTTPヘッダーを介してクロスドメインアクセスを許可するかどうかを承認する必要があります。

response.addHeader(‘Access-Control-Allow-Origin:*’);//允许所有来源访问 
response.addHeader(‘Access-Control-Allow-Method:POST,GET’);//允许访问的方式

解決策 2: jsonp は get リクエストのみをサポートし、post リクエストはサポートしません

使用法: ①dataType を jsonp に変更します。 ②jsonp: "jsonpCallback"— — —バックエンドに送信される実際の値は http://a.a.com/a/FromServlet?userName=644064&jsonpCallback=jQueryxxx ③バックエンドは get リクエストで jsonpCallback を取得します ④コールバック構造体を構築します

$.ajax({
type : "GET",
async : false,
url : "http://a.a.com/a/FromServlet?userName=644064",
dataType : "jsonp",//数据类型为jsonp  
jsonp : "jsonpCallback",//服务端用于接收callback调用的function名的参数
success : function(data) {
alert(data["userName"]);
},
error : function() {
alert('fail');
}
});
 
//后端
        String jsonpCallback = request.getParameter("jsonpCallback");
//构造回调函数格式jsonpCallback(数据)
resp.getWriter().println(jsonpCallback+"("+jsonObject.toJSONString()+")");

JSONP 実装原則

同一オリジン ポリシーでは、特定のサーバー配下のページはサーバー外のデータを取得できません。つまり、一般的な ajax はクロスドメイン リクエストを行うことができません。ただし、img、iframe、script などのタグは例外で、これらのタグは src 属性を通じて他のサーバー上のデータをリクエストできます。 3f1c4e4b6b16bbbd69b2ee476dc4f83a タグのオープン ポリシーを使用すると、ドメインを越えてデータをリクエストできますが、当然ながら、これにはサーバーの協力が必要です。 Jquery の ajax の核心は、XmlHttpRequest を通じてこのページ以外のコンテンツを取得することですが、jsonp の核心は、サーバーが提供する js スクリプトを呼び出すために 3f1c4e4b6b16bbbd69b2ee476dc4f83a タグを動的に追加することです。

通常、JSON データをリクエストすると、サーバーは JSON 型データの文字列を返し、JSONP モードを使用してデータをリクエストすると、サーバーは実行可能な JavaScript コードを返します。 jsonp のクロスドメインの原則は、<script> の src を動的にロードすることであるため、パラメーターは URL 経由でしか渡すことができないため、jsonp の型は取得のみ可能です。 </script>

例:

$.ajax({
    url: &#39;http://192.168.10.46/demo/test.jsp&#39;,        //不同的域
    type: &#39;GET&#39;,                                                        // jsonp模式只有GET 是合法的
    data: {
        &#39;action&#39;: &#39;aaron&#39;
    },
    dataType: &#39;jsonp&#39;,                                              // 数据类型
    jsonp: &#39;jsonpCallback&#39;,                                     // 指定回调函数名,与服务器端接收的一致,并回传回来
})

実際、jquery は内部的に

http://192.168.10.46/demo/test.jsp?jsonpCallback=jQuery202003573935762227615_1402643146875&action=aaron

その後、動的読み込み

<script type="text/javascript"src="http://192.168.10.46/demo/test.jsp?jsonpCallback= jQuery202003573935762227615_1402643146875&action=aaron"></script>

その後、バックエンドは jsonpCallback (パラメーターを渡す) を実行し、実際のパラメーターの形式でデータを送信します。

JSONP モードを使用してデータをリクエストするプロセス全体: クライアントはリクエストを送信し、実行可能な関数名を指定します (ここでは、jQuery がカプセル化プロセスを実行し、自動的にコールバック関数を生成し、データを取り出します)コールバック ハンドルを渡す代わりに、success 属性メソッドを呼び出すと)、サーバーは jsonpCallback 関数名を受け入れ、実際のパラメータ

(jquery 内) の形式でデータを送信します。ソース コードに、サーバーが提供する js スクリプトを呼び出すための 3f1c4e4b6b16bbbd69b2ee476dc4f83a タグを動的に追加することで jsonp が実装されます。jquery は window オブジェクトにグローバル関数をロードします。3f1c4e4b6b16bbbd69b2ee476dc4f83a コードが挿入されると、関数は実行後、3f1c4e4b6b16bbbd69b2ee476dc4f83a は削除されます。同時に、jquery は非クロスドメイン リクエストも最適化しました。リクエストが同じドメイン名にある場合、通常の Ajax リクエストと同様に機能します。)

解決策 3: httpClient 内部転送

実装原理は非常に単純です。サイト B の Ajax を介してサイト A にアクセスしたい場合、結果を取得するには、もちろん ajax クロスドメインの問題が発生しますが、サイト B の結果を取得するためにサイト B にアクセスする場合、クロスドメインの問題は発生しません。この方法は実際には、サイト内の ajax を介してサイト B の HttpClient にアクセスします。 B にアクセスし、HttpClient 経由でリクエストを転送して、サイト A のデータ結果を取得します。ただし、この方法ではリクエストが 2 つ生成されるため非効率ですが、内部リクエストはパケット キャプチャ ツールで解析できないため安全です。

$.ajax({
type : "GET",
async : false,
url : "http://b.b.com:8080/B/FromAjaxservlet?userName=644064",
dataType : "json",
success : function(data) {
alert(data["userName"]);
},
error : function() {
alert(&#39;fail&#39;);
}
});
 
@WebServlet("/FromAjaxservlet")
public class FromAjaxservlet extends HttpServlet{
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
//创建默认连接
CloseableHttpClient httpClient = HttpClients.createDefault();
//创建HttpGet对象,处理get请求,转发到A站点
HttpGet httpGet = new HttpGet("http://a.a.com:8080/A/FromServlet?userName="+req.getParameter("userName")); 
                        //执行
CloseableHttpResponse response = httpClient.execute(httpGet);
int code = response.getStatusLine().getStatusCode();
//获取状态
System.out.println("http请求结果为:"+code);
if(code == 200){
                                //获取A站点返回的结果
String result = EntityUtils.toString(response.getEntity());
System.out.println(result);
                                //把结果返回给B站点
resp.getWriter().print(result);
}
response.close();
httpClient.close();
} catch (Exception e) {
}
}
}

解決策 4: nginx を使用してエンタープライズ レベルのインターフェイス ゲートウェイ メソッドを構築する

www.a.a.com は www のコンテンツを直接リクエストできません.b.b.com では、nginx を使用して、同じドメイン名でも異なるプロジェクト名に基づいてそれらを区別できます。それはどういう意味ですか?それは少し抽象的かもしれません。当社のドメイン名が www.nginxtest.com

であると仮定します。www.nginxtest.com/A を通じて www.a.a.com にアクセスし、それを www.a.a.com

に転送する必要がある場合です。 nginx 経由 www.nginxtest.com/B 経由で www.b.b.com にアクセスし、nginx

経由で www.a.a.com に転送する必要があります。会社のドメイン名にアクセスすると、それは「同じソース」になります。ただし、プロジェクト名は異なります。現時点でのプロジェクト名の役割は、区別して転送を容易にすることだけです。それでも理解できない場合は、まず私がどのように設定したかを見てください:

server {
        listen       80;
        server_name  www.nginxtest.com;
        location /A {
    proxy_pass  http://a.a.com:81;
index  index.html index.htm;
        }
location /B {
    proxy_pass  http://b.b.com:81;
index  index.html index.htm;
        }
    }

我们访问以www.nginxtest.com开头且端口为80的网址,nginx将会进行拦截匹配,若项目名为A,则分发到a.a.com:81。实际上就是通过"同源"的域名,不同的项目名进行区分,通过nginx拦截匹配,转发到对应的网址。整个过程,两次请求,第一次请求nginx服务器,第二次nginx服务器通过拦截匹配分发到对应的网址。

相关免费学习推荐:javascript(视频)

以上がAjaxのクロスドメイン問題を解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。