前端跨域方案-跨域请求代理(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服务做为服务器  然后实现请求。

时间: 2024-10-09 00:09:55

前端跨域方案-跨域请求代理(asp.net handler)的相关文章

vue.js学习之 跨域请求代理与axios传参

vue.js学习之 跨域请求代理与axios传参 一:跨域请求代理 1:打开config/index.js module.exports{ dev: { } } 在这里面找到proxyTable{},改为这样: proxyTable: { '/api': { target: 'http://121.41.130.58:9090',//设置你调用的接口域名和端口号 别忘了加http changeOrigin: true, pathRewrite: { '^/api': ''//这里理解成用'/ap

跨域GET、POST请求

跨域GET.POST请求的小结 重点:跨域POST大量数据: JQuery:$.ajax/$.getJSON支持jsonp格式的跨域,但是只支持GET方式,暂不支持POST: CORS:w3c关于跨域的新方案,res.setHeader('Access-Control-Allow-Origin','*'),兼容IE9+: so,跨域POST是个值得研究的问题啊!万能的JQuery无法跨域POST:鉴于基本国情,CORS也只是适合在移动端玩玩: 相信有同学这样做过: 1 $.ajax({ 2 ty

Angular通过CORS实现跨域方案

以前有一篇很老的文章网上转了很多,包括现在如果你百度"跨域"这个关键字,前几个推荐的都是"Javascript跨域总结与解决方案".看了一下感觉手段有点陈旧了,有一些比如document.domain还有iframe的解决方案委实"丑陋"一些,感觉不再适用于现在一些项目中. 就拿iframe来说作为一个前端工程师,我极为讨厌iframe这种东西.它不光增加了性能上的高负荷,同时也不利于掌控. 在Angular应用中实现跨域的方式相对简单,基本上通

什么是跨域?跨域请求资源的方法有哪些?

1.什么是跨域? 由于浏览器同源策略,凡是发送请求url的协议.域名.端口三者之间任意一与当前页面地址不同即为跨域.存在跨域的情况: 网络协议不同,如http协议访问https协议. 端口不同,如80端口访问8080端口. 域名不同,如qianduanblog.com访问baidu.com. 子域名不同,如abc.qianduanblog.com访问def.qianduanblog.com. 域名和域名对应ip,如www.a.com访问20.205.28.90. 2.跨域请求资源的方法: (1)

springboot shiro 前后端分离,解决跨域、过虑options请求、shiro管理session问题、模拟跨域请求

一.解决跨域.过虑options请求问题 1.创建过虑类 import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; im

处理跨域Options预检请求

//处理跨域Options预检请求 if($_SERVER['REQUEST_METHOD'] == 'OPTIONS'){ //允许的源域名 header("Access-Control-Allow-Origin: *"); //允许的请求头信息 header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization"); //允许的请求

[HTML5_JS跨域]JavaScript跨域总结与解决办法

什么是跨域 JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象.但在安全限制的同时也给注入iframe或是ajax应用上带来了不少麻烦.这里把涉及到跨域的一些问题简单地整理一下: 首先什么是跨域,简单地理解就是因为JavaScript同源策略的限制,a.com 域名下的js无法操作b.com或是c.a.com域名下的对象.更详细的说明可以看下表: 特别注意两点: 第一,如果是协议和端口造成的跨域问题“前台”是无能为力的, 第二:在跨域问题上,域仅仅是通过“URL的首部”来识别而

跨域:跨域及解决方法

一.什么是跨域 广义的跨域包括: 资源跳转:超链接<a>跳转.重定向.表单提交 资源嵌入:link.ifram.script.img,以及css样式中的background:url().@font-face()等外链接 脚本请求:js的ajax请求.js或DOM 中的跨域操作 狭义的跨域:指浏览器同源策略限制的请求 注意:并不是所有广义的跨域操作都不被允许,只有被同源策略限制的跨域操作是不被允许的 二.什么是浏览器同源限制 浏览器为了安全考虑不允许访问不同域下的资源 注意两点: 同源限制只是浏

跨域问题解决方案(HttpClient安全跨域 &amp; jsonp跨域)

1 错误场景 今天要把项目部署到外网的时候,出现了这样的问题, 我把两个项目放到自己本机的tomcat下, 进行代码调试, 运行 都没有问题的, 一旦把我需要调用接口的项目B放到其他的服务器上, 就会报错, 无法通过Ajax调用springMVC的接口, 这是什么原因呢? 当我使用json ajax post请求传递数据的时候在web端出错:XMLHttpRequest cannot loadhttp://ip:8082/security/auth/outside.do. Origin http