Web Api 跨網域呼叫

寫WebApi當然是用來call的
但一開始本機是OK的 掛上server 後就不是那回事
是可以透過 MVC server 內部用 C#部分呼叫
A_client -->A_server -->Call  B_server WebApi
再回覆給 A_client
A_client <-- A_server <--  B_server WebApi
但總覺得不是這樣用
所以嘗試
A_client  -->Call  B_server WebApi
用了
$.ajax({
dataType: "json",
url: url,
data: data,
success: success
});
$.getJSON
怎麼玩都不行
但用瀏覽器直接連是正常的 表server 沒問題

後來想到會不會是瀏覽器跨網域的問題
看了一下 果然是這問題
唉~ 如果不能讓其他網域呼叫 那我自己做就好 寫甚麼 webapi?
一個方法用  iframe 去連B網域再將資料回覆到A_主網頁 這是不得已的做法

再查資料:
$.getJSON 號稱可以跨網域
網上的demo 都是用  "http://api.flickr.com/services/feeds/photos\_public.gne?jsoncallback=?
試 是OK 但是用在自己的 就甚麼都不動....error

後來用 看到 JSONP
$.ajax({
dataType: "jsonp", //data type必須設定成 'jsonp'
url: url,
data: data,
success: success
});
哈!有資料回來了
但還是錯
是javascript 的大錯
看起來是將回傳的 JSON 資料當作是 程式跑....
又有新問題了
再查
原來 JSONP 是用 CallBack 回應
C# MVC Wepapi 部分 還是得改
參考
http://benhumble.blogspot.tw/2016/08/aspnet-webapi-jsonp.html
http://stackoverflow.com/questions/9421312/jsonp-with-asp-net-web-api
在 MVC Global.asax.cs 要加
  1. protected void Application_Start()
  2. {
  3. ……
  4. var config = GlobalConfiguration.Configuration;
  5. config.Formatters.Insert(0, new JsonpMediaTypeFormatter());
  6. }

  下面要加
public class JsonpMediaTypeFormatter : JsonMediaTypeFormatter
{
    private string callbackQueryParameter;

    public JsonpMediaTypeFormatter()
    {
        SupportedMediaTypes.Add(DefaultMediaType);
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/javascript"));

        MediaTypeMappings.Add(new UriPathExtensionMapping("jsonp", DefaultMediaType));
    }

    public string CallbackQueryParameter
    {
        get { return callbackQueryParameter ?? "callback"; }
        set { callbackQueryParameter = value; }
    }

    public override Task WriteToStreamAsync(Type type, object value, Stream stream, HttpContent content, TransportContext transportContext)
    {
        string callback;

        if (IsJsonpRequest(out callback))
        {
            return Task.Factory.StartNew(() =>
            {
                var writer = new StreamWriter(stream);
                writer.Write(callback + "(");
                writer.Flush();

                base.WriteToStreamAsync(type, value, stream, content, transportContext).Wait();

                writer.Write(")");
                writer.Flush();
            });
        }
        else
        {
            return base.WriteToStreamAsync(type, value, stream, content, transportContext);
        }
    }


    private bool IsJsonpRequest(out string callback)
    {
        callback = null;

        if (HttpContext.Current.Request.HttpMethod != "GET")
            return false;

        callback = HttpContext.Current.Request.QueryString[CallbackQueryParameter];

        return !string.IsNullOrEmpty(callback);
    }
}
這樣 MVC 遇到 callback 會包成 function 回傳 javascript 就不會錯
搞定收工














留言

熱門文章