5

C# SOAP Web サービスと、いくつかのカスタムIHTTPHandlerクラスを に展開していhttps://localhost:123ます。http://localhostjQuery を使用して AJAX POST 要求をこれらのハンドラーの 1 つに送信しようとする HTML ページがあります。私は毎回以下を取得します:

XMLHttpRequest を読み込めませんhttps://localhost:123/(S(the_session_id))/MyHandler.ashxhttp://localhostAccess-Control-Allow-Origin でオリジンが許可されていません。

この質問CrossOriginModuleのようにモジュールとCrossOriginHandlerハンドラーを作成しようとしましたが、提案どおりに web.config を更新しました。この質問で提案されているように、ハンドラーに追加しようとしました。このブログ投稿のin / inへの追加に関するweb.configの手順に従ってみました。何も役に立ちません。context.Response.AppendHeader("Access-Control-Allow-Headers", "x-requested-with");ProcessRequestOPTIONSSimpleHandlerFactory-Integrated-4.0system.webServerhandlers

ここに私のハンドラがありProcessRequestます:

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "application/json";
        context.Response.AppendHeader("Access-Control-Allow-Origin", "*");
        context.Response.AppendHeader("Access-Control-Allow-Headers", "x-requested-with");
        context.Response.Write( /* some JSON string */ );
    }

私のweb.configの関連セクションは次のとおりです。

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="Access-Control-Allow-Origin" value="*" />
    </customHeaders>
  </httpProtocol>
  <modules runAllManagedModulesForAllRequests="true">
    <add name="CrossOriginModule" preCondition="managedHandler" type="MyNamespace.CrossOriginModule, MyNamespace, Version=1.0.0.0, Culture=neutral" />
  </modules>
  <handlers>
    <add name="CrossOrigin" verb="OPTIONS" path="*" type="MyNamespace.CrossOriginHandler, MyNamespace, Version=1.0.0.0, Culture=neutral" />
    <remove name="SimpleHandlerFactory-Integrated-4.0" />
    <add name="SimpleHandlerFactory-Integrated-4.0" path="*.ashx" verb="GET,HEAD,POST,DEBUG,OPTIONS" type="System.Web.UI.SimpleHandlerFactory" resourceType="Unspecified" requireAccess="Script" preCondition="integratedMode,runtimeVersionv4.0" />
    <add name="MyHandler" verb="*" path="MyHandler.ashx" type="MyNamespace.MyHandler, MyNamespace, Version=1.0.0.0, Culture=neutral" />
  </handlers>
</system.webServer>

jQuery 1.7.2 を使用して、ハンドラーにリクエストを送信する方法は次のとおりです。

$.ajax({
    url: url,
    data: {user: userName, pass: password},
    type: 'POST',
    dataType: 'json',
    success: function(data, textStatus, jqXHR) {
        ...
    }
});

また、サーバー上のセッションにCookieを使用していないため、<sessionState cookieless="true" />これが問題になる場合はweb.configにあります。私のサーバーは IIS 7.5 です。

URL で機密データを渡していないため、ほとんどのリクエストで JSONP を使用できます。ただし、この 1 つのハンドラーでは、通常の POST を実行する必要があります。これは、平文のパスワードを送信する必要があるためです。SSL 経由ですが、この投稿では、SSL経由であっても URL に機密データを渡さないことをお勧めします。したがって、AJAX を介して https URL に対して POST 要求を実行し、JSON を取得する必要があります。要求元のページはサーバーと同じホスト上にありません。

編集:私が試した他のいくつかのこと:

私の web.confighttpProtocolセクションを変更する:

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Methods" value="OPTIONS,POST,GET"/>
    <add name="Access-Control-Allow-Headers" value="x-requested-with"/>
    <add name="Access-Control-Allow-Origin" value="*" /><!-- Also tried http://localhost -->
  </customHeaders>
</httpProtocol>

に追加context.Response.AppendHeader("Access-Control-Allow-Methods", "POST");しましたProcessRequest。またcontext.Response.AppendHeader("Access-Control-Allow-Methods", "POST,OPTIONS");、jQueryajaxオプションを includeに変更しようとしましたがcontentType: 'application/json'、これにより、POST の代わりに OPTIONS 要求が行われますが、これはまだ失敗します。

の web.config にあるすべてのカスタムIHTTPHandlerクラスを一覧表示する必要があり<handlers>ますか? 私はMyHandler今そこにいますverb="*"が、それは役に立たないようです。

編集:さらに奇妙です。ログ出力に基づいて、サーバー側に POST すると、リクエストが実際にサーバー側で通過しているように見えますが、ブラウザは拒否されたように動作し、「オリジン localhost は許可されていません」と表示されます。したがって、サーバーへの AJAX POST は希望どおりに認証しますが、ブラウザーは要求をキャンセルし、Chrome コンソールにエラーが表示されるため、successイベント ハンドラーはトリガーされません。

4

2 に答える 2

1

これはばかげており、何が起こっているのかわかりませんが、POST は実行されており、認証はサーバーで行われていますが、ブラウザーはそれが許可されていないと判断したため、失敗しました。セッションがまだアクティブで、ユーザーが認証されているかどうかを通知する JSONP をサポートするハンドラーが既にあるので、AJAX 呼び出しを次のように変更しました。

$.ajax({
    url: url,
    data: {user: userName, pass: password},
    type: 'POST',
    dataType: 'json',
    complete: function(jqXHR, textStatus) {
        checkIfAuthenticated(
            function() { // authenticated
                onComplete(true, null)
            },
            function() { // not authenticated
                onComplete(false, textStatus);
            }
        );
    }
});

そのため、「XMLHttpRequest cannot load https://.../AuthHandler.ashx. Origin http://localhostis not allowed by Access-Control-Allow-Origin」というエラーが Chrome コンソールに表示され、Chrome の [Network] タブには POST リクエストがキャンセルされたものとして表示されます。checkIfAuthenticated認証が失敗したかどうかを確認するために、関数を介してここで追加のリクエストを行う必要がありますが、機能します。

ProcessRequestサーバー上の私のものはMyHandler次のようになります。

public void ProcessRequest(HttpContext context)
{
    context.Response.ClearHeaders();
    string origin = context.Request.Headers["Origin"];
    context.Response.AppendHeader("Access-Control-Allow-Origin",
        string.IsNullOrEmpty(origin) ? "*" : origin);
    string requestHeaders = context.Request.Headers["Access-Control-Request-Headers"];
    context.Response.AppendHeader("Access-Control-Allow-Headers",
        string.IsNullOrEmpty(requestHeaders) ? "*" : requestHeaders);
    context.Response.AppendHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
    context.Response.ContentType = "application/json";
    context.Response.Write(/* JSON response */);
    context.Response.Flush();
}

そして、これが私のweb.configの関連セクションが次のようになったものです:

  <system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Methods" value="OPTIONS,POST,GET"/>
        <add name="Access-Control-Allow-Headers" value="x-requested-with"/>
        <add name="Access-Control-Allow-Origin" value="*" />
      </customHeaders>
    </httpProtocol>
    <handlers>
      <add name="MyHandler" verb="*" path="MyHandler.ashx" type="MyNamespace.MyHandler, MyNamespace, Version=1.0.0.0, Culture=neutral" />
    </handlers>
  </system.webServer>

これはばかげた回避策であるため、リクエストが実際に許可されたことをブラウザに納得させるソリューションを望んでいます。

于 2012-06-28T16:08:29.423 に答える