JSONを有効にするためのWebInvoke属性とWebHttpバインディングで装飾されたWCFサービスがあります。このサービスは、クロスドメインで機能するようにするまで、JavaScript からアクセスできます。これをクロスドメインで機能させる方法をお勧めできますか?
プロキシ Web ハンドラーを作成しようとしましたが、WebHttpRequest がアクセスしようとするたびに「Bad Request」が発生します。
JSONを有効にするためのWebInvoke属性とWebHttpバインディングで装飾されたWCFサービスがあります。このサービスは、クロスドメインで機能するようにするまで、JavaScript からアクセスできます。これをクロスドメインで機能させる方法をお勧めできますか?
プロキシ Web ハンドラーを作成しようとしましたが、WebHttpRequest がアクセスしようとするたびに「Bad Request」が発生します。
私がしなければならなかったのは、プロキシを作成することでした。クロス ドメイン リクエストは GET 動詞でのみ機能し、POST では機能しません。私のリクエストはすべてプロキシを通過し、POST の場合は典型的なプロキシとして機能します。リクエストが GET を使用している場合は、それを POST に変換する必要があります。(私は、サービス契約で動詞として POST を指定しています)。
クライアント側では、JQuery の josnp (パディング付きの json) 機能を使用して、正しい情報をクエリ文字列に追加します。
private static readonly Properties.Settings settings = new Properties.Settings();
public void ProcessRequest(HttpContext context)
{
try
{
string wcfAddress = context.Request.QueryString["WcfAddress"];
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(settings.WCFAddress + wcfAddress);
request.ContentType = "application/json";
request.Method = "POST";
if (context.Request.RequestType == "GET")
{
string callback = context.Request.QueryString["callback"];
string qs = context.Request.QueryString[null];
byte[] body = body = Encoding.UTF8.GetBytes(qs);
request.ContentLength = body.Length;
request.GetRequestStream().Write(body, 0, body.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
string contents = reader.ReadToEnd();
contents = callback + "(" + contents + ");";
context.Response.ContentType = "application/json";
context.Response.Write(contents);
response.Close();
reader.Close();
}
}
else if (context.Request.RequestType == "POST")
{
byte[] body = new byte[context.Request.ContentLength];
context.Request.InputStream.Read(body, 0, body.Length);
request.ContentLength = body.Length;
request.GetRequestStream().Write(body, 0, body.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
{
string contents = reader.ReadToEnd();
context.Response.ContentType = "application/json";
context.Response.Write(contents);
response.Close();
reader.Close();
}
}
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.ToString());
}
}
この優れた記事シリーズの第 1 部から第 4 部で説明されている手順に従うと、問題のない解決策が得られます。問題なく本番環境で使用しています。
ただし、すべてのブラウザで動作するようにするには、1 つの調整を行う必要があります。CorsDispatchMessageInspector.BeforeSendReply
チェックをコメントアウトします。
if (state.Message != null)
それ以外の場合、「Allow」ヘッダーはプリフライト リクエストにのみ適用され、実際のリクエストには適用されません。
問題を解決するには、次の手順を実行します
Global.asax を作成し、次のコードを追加して、Ajax クロスドメイン POST を有効にします。
public void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST,OPTIONS");
if ((HttpContext.Current.Request.HttpMethod == "OPTIONS"))
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}
}
}