2017-03-07 25 views
1

IISではなく、実行可能ファイルによってホストされるWCFサービスに対して、クロスドメインPOST要求を行う必要があります。この目的は、WCFサービスがこれらのIDに関連するログを検索して返すために使用する、WebクライアントからのID文字列の配列を渡すことです。jQueryのAjaxからWCFサービスへのCORS POSTを有効にする

私は近くにいると思います。欠けている主な部分は、カスタムヘッダーを追加するapp.configファイルの構成です。

<httpProtocol> 
    <customHeaders> 
    <!-- http://stackoverflow.com/questions/12458444/enabling-cross-origin-resource-sharing-on-iis7 --> 
    <add name="Access-Control-Allow-Headers" value="X-Requested-With,Content-Type,Accept" /> 
    <add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,OPTIONS" /> 
    <add name="Access-Control-Allow-Credentials" value="true" /> 
    <add name="Timing-Allow-Origin" value="*" /> 
    </customHeaders> 
</httpProtocol> 

上記のコードと私の問題は、それが存在するということです。私は他の場所で私の溶液中に含まれて私が探している動作を説明し、他のサービスのためのweb.configファイルがあることに注意しますIISホスティングサービス用のweb.configファイル。実行可能ファイルでホストしている私のサービスのためにカスタムヘッダーをapp.configに記述する必要があります(私は以下の質問の方法を提供しています)。

私は日のためにこれを解決しようとしてきた、そしてこれまで、さておき、私はとの助けを探していた構成の混乱から、それはこの構文は、サービスを呼び出すための大丈夫であるというのが私の理解です:

 var settings: JQueryAjaxSettings = {}; 

     settings.async = true; 
     settings.crossDomain = true; 
     settings.url = this.getLogEntriesByIdResource; 
     settings.method = "POST"; 
     settings.type = "POST"; 
     settings.dataType = 'JSON'; 
     settings.headers = { 
      "content-type": "application/json", 
      "cache-control": "no-cache" 
     } 
     settings.data = JSON.stringify(ids); 

     jQuery.ajax(settings).done(function (response) { 
      console.log(response); 
     }); 

と、これは上記のコードを呼び出すWCFエンドポイントで良いパスである:

[OperationContract, CorsEnabled] 
    [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Bare, 
     RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, 
     UriTemplate = "GetLogEntriesById")] 
    [Description("Request entities or entity updates for a particular time and place")] 
    public List<LogEntryInfo> GetLogEntriesById(string[] ids) 
    { 
     List<LogEntryInfo> results = new List<LogEntryInfo>(); 
     List<ILogEntry> rels = Gateway.MongoDbInstance.ReturnLogEntries(ids.ToList()); 
     rels.ForEach(e => results.Add(new LogEntryInfo(e))); 
     return results; 
    } 

はさらに、ここに私のwebServiceHostをセットアップするコードは次のとおりです。

public LogEntryRestService(string baseAddress, string endpoint) 
    { 
     _baseAddress = baseAddress; 
     _endpoint = endpoint; 

     _webServiceHost = new WebServiceHost(this, new Uri(baseAddress)); 

     var webBinding = new WebHttpBinding(WebHttpSecurityMode.None) { CrossDomainScriptAccessEnabled = true }; 
     ServiceEndpoint ep = _webServiceHost.AddServiceEndpoint(typeof(LogEntryRestService), webBinding, endpoint); 

     WebHttpBehavior webBehavior = new WebHttpBehavior(); 
     webBehavior.HelpEnabled = true; 

     ep.EndpointBehaviors.Add(webBehavior); 
     ep.EndpointBehaviors.Add(new EnableCorsEndpointBehavior()); 

     Program.LogMessage(string.Format("Initializing LogEntry REST endpoint BaseAddress: {0} EndpointName: {1}", 
       _webServiceHost.BaseAddresses[0], endpoint)); 

     _webServiceHost.Open(); 
    } 

また、エンドポイントにJSON本体が指定されたPostmanからの標準呼び出しが完全に機能していることを指摘します。 Postman(Chrome拡張機能)は、Webページと同じ方法でCORSに準拠していないことに気付いています。私の呼び出しているajaxコードは、PostmanがjQuery ajaxに提供しているのと同じ提案された呼び出しコードなので、CORSの問題があることを意味していると思います。

私はこの設定とCORSの穏やかな気持ちから少し疲れました。私は本当に新鮮な目と助けに感謝します!

UPDATE

だから私は対照的に、私の地元のボックスにデバッグするために、実際のサーバーインスタンスに(私は上記の共有しているものを)私の現在のコードを展開しようとしたし、すべてが正常に動作していることがわかりました。私はです。しかし、まだ私は解決したいと思うローカルでエラーを受け取ります。私はまた、リクエストメソッドがあるPOSTは、それが何であるかということを、「OPTIONS」として示されていることに注意しましょう

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
    <title>Service</title> 
    <style>BODY { color: #000000; background-color: white; font-family: Verdana; margin-left: 0px; margin-top: 0px; } #content { margin-left: 30px; font-size: .70em; padding-bottom: 2em; } A:link { color: #336699; font-weight: bold; text-decoration: underline; } A:visited { color: #6699cc; font-weight: bold; text-decoration: underline; } A:active { color: #336699; font-weight: bold; text-decoration: underline; } .heading1 { background-color: #003366; border-bottom: #336699 6px solid; color: #ffffff; font-family: Tahoma; font-size: 26px; font-weight: normal;margin: 0em 0em 10px -20px; padding-bottom: 8px; padding-left: 30px;padding-top: 16px;} pre { font-size:small; background-color: #e5e5cc; padding: 5px; font-family: Courier New; margin-top: 0px; border: 1px #f0f0e0 solid; white-space: pre-wrap; white-space: -pre-wrap; word-wrap: break-word; } table { border-collapse: collapse; border-spacing: 0px; font-family: Verdana;} table th { border-right: 2px white solid; border-bottom: 2px white solid; font-weight: bold; background-color: #cecf9c;} table td { border-right: 2px white solid; border-bottom: 2px white solid; background-color: #e5e5cc;}</style> 
    </head> 
    <body> 
    <div id="content"> 
     <p class="heading1">Service</p> 
     <p xmlns="">Method not allowed. Please see the <a rel="help-page" href="http://localhost/LogEntryService/help">service help page</a> for constructing valid requests to the service.</p> 
    </div> 
    </body> 
</html>         

:そのエラーは私のローカルデバッグクライアントは私のローカルデバッグサービスを呼び出して、この応答によって記述されていますこのコードをすべて専用サーバーで実行しているときの動作です。

POSTメソッドがデフォルトでOPTIONSメソッドを使用する理由は何ですか?私はこれを解決するために、IIS以外のホストされたWebサービスでCORSを有効にする必要があるという点で正方形に戻っていると思います。助けや洞察力をお寄せいただきありがとうございます。

UPDATE

Iは、要求と要求のクロームのdevのツールのネットワークビューのシオマネキ検査の両方の画面のキャップの下に用意しました。

Fiddler inspection フィドラー検査^

Chrome dev tools request and response クロームのdevのツール要求と応答^

+1

私はjqueryのエキスパートではありませんが、content-type:application/jsonがプリフライトレスポンスをトリガーします。私はそれを知っています。あなたはエラーが起こっていますか?私はあなたのポストに何の誤りも見ませんでした。 – Puerto

+0

ああ、私はエラーを追加してください、それを指摘していただきありがとうございます。どういうわけかJSONコンテンツタイプを指定する必要があることはわかっていますが、これは文字列の配列をWebメソッドに渡すことを計画しているからです。私はもともと掲示して以来、いくつかの進歩を遂げました、私は今私の投稿を更新します。見ていただきありがとうございます! – ThePartyTurtle

+1

あなたはフィドラーを持っていますか?私はフィドラーの交通を見ているだろう。ヘッダーが変更されている可能性が最も高い場合は、カスタムヘッダーを送信していないことを意味し、送信する値を変更するデフォルトのヘッダーが表示されます(ただし、この方法に影響するかどうかはわかりません)。これが起こっている場合は、アプリケーション内のcors設定を完全に確認する必要があります。また、HTML形式でエラーメッセージを投稿しないで、エラーメッセージを投稿してください。 – Puerto

答えて

2

これはあなたの問題がどこにあるかあなたが打破に役立つはずです。プリフライトだったスクリーンショット(主にフィドル)。それらはオプションです。しかし、プリフライトをパスすると、Postが送信され、それ以降は別のエントリが存在するはずです。ここでは、フィドルの良い投稿の例です。

プリフライト(生):

直後

要求(生)に続いて

OPTIONS http://localhost:5000/api/values/dui/ HTTP/1.1 
Host: localhost:5000 
Connection: keep-alive 
Access-Control-Request-Method: POST 
Origin: http://evil.com/ 
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 
Access-Control-Request-Headers: access-control-allow-origin, content-type 
Accept: */* 
Referer: http://localhost:3000/validator 
Accept-Encoding: gzip, deflate, sdch, br 
Accept-Language: en-US,en;q=0.8 

:私のAPIから

POST http://localhost:5000/api/values/dui/ HTTP/1.1 
Host: localhost:5000 
Connection: keep-alive 
Content-Length: 17 
access-control-allow-origin: * 
accept: application/json 
Origin: http://evil.com/ 
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36 
content-type: application/json 
Referer: http://localhost:3000/validator 
Accept-Encoding: gzip, deflate, br 
Accept-Language: en-US,en;q=0.8 

{"name":"test"} 

応答(生):

HTTP/1.1 200 OK 
Date: Thu, 09 Mar 2017 16:42:27 GMT 
Content-Type: application/json; charset=utf-8 
Server: Kestrel 
Content-Length: 57 

{"name":"Hey Test, Im The Dude man.","link":"dude.png"} 

私はしませんあなたはプリフライトを過ごしています。 Chromeの応答がどこから来ているのかわからないが、プリフライトを渡すように設定する必要がある。したがって、アプリケーションのコードには、適切なcors設定とサーバー(web.configを使用するIIS)が必要です。私はdotnet core webApiとReact UIでCorsを正しく設定して同様の問題に遭遇しました(表示here)。あなたは私がここでそれをどのように処理したかを見ることができます。お役に立てれば。しかし、私はプリフライトに焦点を当て、通過することを確認します。もしそうなら、投稿自体に移動します。たとえば、設定している投稿(application/json)にコンテンツタイプが表示されていない場合、カスタムヘッダーがどこかに詰まってしまいます。私はあなたがそれを設定する必要がありますが、オプションはプリフライトが正常であることを正確には特定できません申し訳ありません。私はそれに焦点を当てません。ソリューションを追加しましたため

*******アップデートは**********

私はあなたの問題を解決するために、このようなものが必要と考えています。基本的に、WebService自体にヘッダーを追加する必要があります。

"Global.asaxファイルを追加し、次のコードをApplication_BeginRequestに追加します。次に、コードスニペットを示します。

protected void Application_BeginRequest(object sender, EventArgs e) 
{ 
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost"); 
if (HttpContext.Current.Request.HttpMethod == "OPTIONS") 
{ 
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE"); 

    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept"); 
    HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000"); 
    HttpContext.Current.Response.End(); 
} 
} 

完全参照はhereです。記事はかなり最近です。これにより、問題が解決されます。

+0

あなたはハンマーで釘を打っています。私の問題は、プレフライトで私のサービスをOKにして、次のPOSTができるようにするのが本当に難しいことです。時間と説明にとても感謝します! – ThePartyTurtle

+1

@ ThePartyTurtleは、私が投稿したソリューションのアップデートを参照してください。それが解決することを願っています。 – Puerto

+1

@ ThePartyTurtle、それはそれを解決しましたか? – Puerto

関連する問題