码迷,mamicode.com
首页 > Web开发 > 详细

前端跨域方案-跨域请求代理(asp.net handler)

时间:2017-02-27 19:18:34      阅读:309      评论:0      收藏:0      [点我收藏+]

标签:mat   substr   baseurl   插件   post   isnull   cat   开发人员   ash   

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

 

前端跨域方案-跨域请求代理(asp.net handler)

标签:mat   substr   baseurl   插件   post   isnull   cat   开发人员   ash   

原文地址:http://www.cnblogs.com/kongkonglonglong/p/6475418.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!