现在技术开发偏向于使用统一的接口处理浏览器或者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服务做为服务器 然后实现请求。