現在技術開發偏向於使用統一的接口處理瀏覽器或者app的http請求。
大家都知道因為瀏覽器的同源策略的原因 js直接請求webapi 接口會有一些問題,即使做好服務器端的配置 同樣會有不少的 問題 並且會有瀏覽器的兼容性 而使用jsonp 又需要服務器端對返回數據做相關處理 所以考慮考慮使用代理來解決前端跨域請求的問題。
代理程序走asp.net的一般處理程序,來實現前端js請求的接受然后轉發到api站點。
關鍵點:
1.使用url參數的方式傳送api接口的站點路徑
http://test.m.***.com/handler/api.ashx?apipath=api/ArticlesApi/getlist
2.讀取url參數追加到接口請求中(注意把apipath參數過濾掉)
3.讀取post請求中的請求體中的json數據 放到接口的請求中
using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Configuration; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Web; namespace m.lingfo.com.handlers { /// <summary> /// api 的摘要說明 /// </summary> public class api : IHttpHandler { string domain = "localapi.***.com"; public void ProcessRequest(HttpContext context) { string url = "http://localapi.***.com"; string IsDebug = ConfigurationManager.AppSettings["IsDebug"]; if (Convert.ToBoolean(IsDebug)) { url = ConfigurationManager.AppSettings["localapi"]; } else { url = ConfigurationManager.AppSettings["siteapi"]; } //獲取請求的url參數 string baseurl; NameValueCollection nvc = ParseUrl(context.Request.RawUrl, out baseurl); StringBuilder sb = new StringBuilder(); foreach (var item in nvc.AllKeys) { if (item.Equals("apipath")) { continue; } sb.AppendFormat("&{0}={1}",item,nvc[item]); } string json = "{\"name\":\"aa\",\"mobile\":\"130\"}"; string Path = string.Format("{0}/{1}",url,nvc["apipath"]);//url中追加的apipath參數 作為接口的唯一地址標識 WebRequest request = WebRequest.CreateHttp(Path); request.Method = context.Request.HttpMethod; request.ContentType = "application/json"; //獲取請求的Form數據 NameValueCollection nvc2 = context.Request.Form; if (!context.Request.HttpMethod.ToLower().Equals("get")) { JObject formdata = new JObject(); foreach (var item in nvc2.AllKeys) { formdata[item] = nvc2[item]; } json = JsonConvert.SerializeObject(formdata); if (!string.IsNullOrEmpty(json)) { using (var streamWriter = new StreamWriter(request.GetRequestStream())) { streamWriter.Write(json); streamWriter.Flush(); streamWriter.Close(); } } } System.Net.WebResponse response = request.GetResponse(); StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8")); string ReturnVal = reader.ReadToEnd(); reader.Close(); response.Close(); context.Response.ContentType = "application/json"; context.Response.Write(ReturnVal); context.Response.End(); } /// <summary> /// 分析url鏈接,返回參數集合 /// </summary> /// <param name="url">url鏈接</param> /// <param name="baseUrl"></param> /// <returns></returns> private static System.Collections.Specialized.NameValueCollection ParseUrl(string url, out string baseUrl) { baseUrl = ""; if (string.IsNullOrEmpty(url)) return null; System.Collections.Specialized.NameValueCollection nvc = new System.Collections.Specialized.NameValueCollection(); try { int questionMarkIndex = url.IndexOf('?'); if (questionMarkIndex == -1) baseUrl = url; else baseUrl = url.Substring(0, questionMarkIndex); if (questionMarkIndex == url.Length - 1) return null; string ps = url.Substring(questionMarkIndex + 1); // 開始分析參數對 System.Text.RegularExpressions.Regex re = new System.Text.RegularExpressions.Regex(@"(^|&)?(\w+)=([^&]+)(&|$)?", System.Text.RegularExpressions.RegexOptions.Compiled); System.Text.RegularExpressions.MatchCollection mc = re.Matches(ps); foreach (System.Text.RegularExpressions.Match m in mc) { nvc.Add(m.Result("$2").ToLower(), m.Result("$3")); } } catch { } return nvc; } public bool IsReusable { get { return false; } } } }
最后在分享下自己的一個前端請求代理接口的例子(封裝成了jQuery插件):
$.dyiajax = function (apipath, data, ajaxtype, success, fail) { var url = "/handlers/api.ashx?apipath=" + apipath; $.ajax({ url: url, type: ajaxtype, dataType: 'json', data: data, success: success, fail: fail }); } //調用例子 $.dyiajax("/api/ArticlesApi/downrecommendlist?time=" + time + "&length=10", {},"get", function (data) {}, function () {});
現在技術上要求前后端分離 不能要求前端開發人員都能搭建 vs環境 所以 又寫了一個 node的代理服務 這樣的話前端開發人員只需要在本地啟動node服務做為服務器 然后實現請求。