jQueryを使用してリダイレクトに従うためのajaxリクエストを防ぐ方法


102

私はjQuery ajax関数を使用してWebサービスにアクセスしますが、サーバーは、問題を説明するステータスコードを含む応答を返す代わりに、問題を説明する200ヘッダーを持つページにリダイレクトされます。これを変更することはできないので、クライアントで何らかの方法で解決する必要があります。

例:リクエストが見つからないURLに送信されるため、別の場所への302リダイレクトを受け取ります。新しいリクエストが送信され、200 OKが返されるため、エラーコールバックが起動しません。

ajaxリクエストがリダイレクトをたどり、代わりにコールバック(できればエラーメソッド)を呼び出すのを防ぐ方法はありますか?または、クライアントでリダイレクトが発生したかどうかを検出することはできますか?



8
あなたのバックエンドではなく、404の、見つからなかったため302が報告されていることが奇数である
ジェイクFeasel

回答:


96

あなたの質問は興味深いと思いますが、問題全体が私にはもっと誤解されているようです。少なくとも問題の理解を説明しようと思います。

サイレント(透明)のリダイレクトはの一部であり、XMLHttpRequest仕様書(参照ここでは特に言葉「...透過的にリダイレクトをたどるの...」)。標準では、ユーザーエージェント(Webブラウザー)特定の種類の自動リダイレクトを防止または通知できることのみを述べていますが、これはの一部ではありませんXMLHttpRequest。これは、HTTPクライアント構成(OS構成)またはWebブラウザー構成の一部です。したがってjQuery.ajax、リダイレクトを防止できるオプションはありません。

HTTPリダイレクションがHTTPプロトコルの一部であり、の一部ではないことがわかりますXMLHttpRequest。したがって、それは抽象化の別のレベルまたはネットワークスタック上にあります。たとえば、からのデータは、XMLHttpRequestHTTPプロキシまたはローカルブラウザキャッシュから取得でき、HTTPプロトコルの一部です。ほとんどの場合クライアントではなくデータを提供するサーバーがキャッシュに影響を与える可能性があります。

質問の要件と、通信中のWebサーバーのIPアドレスの変更やIPルートの変更を防ぐための要件を比較できます。いくつかのシナリオではすべてのものが面白い場合がありますが、通信スタックの別のレベルの一部があり、jQuery.ajaxまたはで管理できませんXMLHttpRequest

XMLHttpRequestクライアント構成は、リダイレクトを防ぐためのオプションを持つことができることを標準と言います。私がよく知っている "Microsoft world"の場合、値でオプションを設定するために使用できるWinHttpSetOption関数を見ることができます。別の方法は、値でのオプションの使用です。Windowsで使用できるもう1つの機能は、WinHttpSetStatusCallback関数です。これは、コールバック関数がのようないくつかの通知を受け取ったことを設定できます。WINHTTP_OPTION_DISABLE_FEATUREWINHTTP_DISABLE_REDIRECTSWINHTTP_OPTION_REDIRECT_POLICYWINHTTP_OPTION_REDIRECT_POLICY_NEVERWINHTTP_CALLBACK_FLAG_REDIRECT

したがって、一般的に要件を実装することは可能ですが、ソリューションはおそらくオペレーティングシステムやWebブラウザから独立しておらず、jQuery.ajaxまたはのレベルではありませんXMLHttpRequest


2
素晴らしい洞察力を備えた素晴らしい答え!私はカールについてある程度の経験があります。そのため、あなたが言うように同様のフラグを設定できます。そのような指示がブラウザに渡されることを期待していましたが、あなたの回答から、期待される動作は、最初のリクエストがサーバーによって割り当てられた場所に送信されたかのようにリダイレクトに従うことであることを理解しています。
ヨルゲン

@ヨルゲン:どういたしまして!ほとんどのシナリオでは、リダイレクトはまったく問題ありません。jQuery.ajaxを使用するコンテキストや、リクエストの送信先のWebサーバーを完全に制御できるかどうかは説明しません。したがって、実際に問題を解決できる他のアドバイスを提供することは困難です。
Oleg

私はサーバー側を制御していません、私は恐れています。私の最良のオプションは、応答コンテンツを分析または検証することです。
ヨルゲン

@Jørgen:リダイレクトが問題になるのはなぜですか?サーバーが別の場所のページを一時的または永続的に移動した場合、元のリクエストを新しい場所にリダイレクトできます。絶対大丈夫です。管理者は、たとえばサーバーでの復元操作やその他のサポート作業中にリダイレクトを実行するようにWebサーバーを設定できます。DNSのあるURLでサーバーに要求すると、管理者はIPマッピングを別のサーバーに変更できます。彼はDNS再構成と同じ方法でHTTPリダイレクトを行うことができます。あなたの問題は何ですか?
Oleg

私の問題は、リダイレクトが一般的なエラーページに移動することです。サーバーを別の方法で設定する必要があることはわかっていますが、今のところ、この状況の解決策をそのまま見つける必要があります。
ヨルゲン

23

それが可能だとは思いません。基盤となるライブラリ(XHR)は、新しい要求を透過的に行います。そうは言っても、私がこれらの状況(通常、ログインページに移動するセッションタイムアウトタイプの取引)で行ったことは、カスタム応答ヘッダーを送り返すことです。また、そのヘッダーの存在を確認し、存在する場合は適切に応答する(例えば、ページ全体をログイン画面にリダイレクトする)グローバルajaxハンドラーをセットアップしました。

興味がある場合は、カスタムヘッダーを監視する必要があるjQueryコードを次に示します。

/* redirects main window when AJAX request indicates that the session has expired on the backend. */
function checkSession(event, xhr, ajaxOptions)
{
    if (xhr.readyState == 4)
    {
        if(xhr.getResponseHeader("Login-Screen") != null && xhr.getResponseHeader("Login-Screen").length)
        {
            window.location.href='sessionExpired.html'; //whatever
        }
    }
}

$(document).ajaxComplete(checkSession)

1
おかげで、応答を分析して、同様のアプローチを解決する必要があると思います。
ヨルゲン

11

通話がリダイレクトされたかどうかを確認する機能が見つかりました。これはxhr.state()です。「拒否」された場合、リダイレクトが発生しました。

成功したコールバックの例:

request.success(function(data, textStatus, xhr)
{
    if(xhr.state() == "resolved")
    {
        //no redirection
    }
    if(xhr.state() == "rejected")
    {
        //redirection
    }
});

エラーコールバックの例:

request.error(function(xhr, textStatus)
{
    if (xhr.state() == "rejected")
    {
        //redirection
        location.href = "loginpage";
    } else
    {
        //some other error happened
        alert("error");
    }
});

1
回答のヒントは、物事をうまく進めるのに非常に役立ちました。他の人を助けるメモのために、SiteMinderと統合されたセキュリティを持つWebSphere Portalがあります。リソースのURLへのAjax呼び出しを必要とするポートレットがあり、タイムアウトすると透過的なリダイレクトが発生しますが、ログインページにリダイレクトする方法をどこにも処理できません。「拒否」されているjqXHR.state()を確認すると、確実に役立ちます。改めて感謝いたします。
Uresh Kuruhuri、2015

すばらしい発見ですが、リダイレクトだけでなくプロミスが拒否された場合でも「拒否」状態がトリガーされる可能性があるため、誤検知が発生する可能性があります。jQueryは「拒否された」状態がいつ
Nitin

1

私は、以前に応答したコーダーの洞察に満ちた知恵を追加することはできませんが、他の人が知っておくと役立つと思われる特定のケースを追加します。

SharePointのコンテキストでこの302サイレントリダイレクトに遭遇しました。SharePointサブサイトにpingを送信する単純なJavascriptクライアントコードがいくつかあり、200 HTTP応答を受信すると、それはを介してそのサイトに再配置されますwindow.location。それ以外のものを受け取った場合、サイトが存在しないことをユーザーに通知します。

ただし、サイトは存在するがユーザーに権限がない場合、SharePointはサイレントにAccessDenied.aspxページにリダイレクトします。SharePointはすでにサーバー/ファームレベルでHTTP 401認証ハンドシェイクを実行しています-ユーザーはSharePointにアクセスできます。しかし、サブサイトへのアクセスは、何らかのデータベースフラグを使用して処理されると思います。サイレントリダイレクトは「else」句をバイパスするため、自分のエラーをスローすることはできません。私の場合、これはショーストッパーではありません-一貫した予測可能な動作です。しかし、それは少し意外であり、その過程でHTTPリクエストについて何かを学びました!


1

私は同じことに興味があり、Takmanによって言及されstate()方法を見つけることができず、自分で少し掘り下げました。答えを求めてここに現れる人々のために、ここに私の発見があります:

何度も述べたように、リダイレクトを防ぐことはできませんが、リダイレクトを検出することはできます。MDNによると、のresponseURLを使用できますXMLHttpRequestObject。これには、すべてのリダイレクトの後に、応答の最終的なURLが含まれます。唯一の注意点は、それがInternet Explorerでサポートされていないことです(Edgeにはサポートされています)。以来xhr/ jqXHRに渡さsuccess/ donejqueryの機能実際の拡張であるXMLHttpRequest、それはあまりにも、そこには利用可能であるべきです。


0

リダイレクトが2回ないため、200ページの応答を受け取ったと思います。404ページは有効期限が切れていないため、キャッシュに保存されます。つまり、ブラウザが2回目にキャッシュ内のページを表示するということです。ajax jqueryには「キャッシュ」というプロパティがあります。 http://api.jquery.com/jQuery.ajax/

"false"と書いてください


0

XmlHttpRequestsで次の場所のリダイレクトを無効にすることはできませんが、fetch()を使用する場合です。

fetch('url', {redirect: manual});

FetchはリダイレクトされたURLが何であるかを通知しません。動作を無効にすることもできますが、「redirect:manual」は、ユーザーが名前インテントを使用してリダイレクトを処理できるようにすることを意図していません。
lcjury

-2

これがあなたのケースに当てはまるかどうかはわかりませんが、AJAX関数で特定のステータスコードに応答するコードを記述できます-

$.ajax({
    url: '/admin/secret/data',
    type: 'POST',
    contentType: 'application/json; charset=utf-8',
    statusCode: {
        200: function (data) {
            alert('302: Occurred');
            // Bind the JSON data to the UI
        },
        401: function (data) {
            alert('401: Occurred');
            // Handle the 401 error here.
        }
    }
});

9
OPは彼が言ったので、私は、これは適用されないと思う常に起因するバックグラウンドで起こってリダイレクトに200のステータスコードを取得します...
はいバリー

-4

ajaxリクエストの場合のリクエストヘッダーでは、次のようになります。

X-Requested-With    XMLHttpRequest

サーバー側のこの基準により、リクエストをフィルタリングできます。


彼は要求ではなく応答を確認したいと思っていました(すでに自分が制御しています)
はいバリー

たぶんGfoxは、3xxを返すajaxリクエストは無意味であることを示唆しているかもしれません。たとえば、この種のリクエストをフィルタリングして403を返すことができます。フォーム認証を必要とするページを提供するWebサイトがあり、それらのページがajax呼び出しも行い、承認ロジックを1か所に配置したい場合、私にとってそれは有効な答えです。
maciejW 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.