zoukankan      html  css  js  c++  java
  • 前端跨域方案-跨域请求代理(asp.net handler)

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

  • 相关阅读:
    Mybatis 使用Mybatis时实体类属性名和表中的字段名不一致
    getResourceAsStream 地址
    Memory Allocation with COBOL
    静态call 动态call LINK
    反编译
    eclipse 设置英文
    WAR/EAR 概念
    application.xml
    对ContentProvider中getType方法的一点理解
    总结使人进步,可视化界面GUI应用开发总结:Android、iOS、Web、Swing、Windows开发等
  • 原文地址:https://www.cnblogs.com/kongkonglonglong/p/6475418.html
Copyright © 2011-2022 走看看