2020欧洲杯官方投注-2020欧洲杯官方投注网址应用

来源:http://www.boundlesssupremacy.com 作者:win7 人气:101 发布时间:2019-08-23
摘要:行使代理消除跨站点须求和跨站点上传文件 在做Web系统的时候,大家日常会利用Ajax工夫来兑现异步加载数据的意义,初步的时候我们的体系独有多个,但随着事情的开发进取,大家的

行使代理消除跨站点须求和跨站点上传文件

在做Web系统的时候,大家日常会利用Ajax工夫来兑现异步加载数据的意义,初步的时候我们的体系独有多个,但随着事情的开发进取,大家的Web系统或然有多数个,何况各个系统大概都以多个独自的站点,那么当大家一贯动用Ajax本领来拜谒别的站点时,就能出现意外。

一旦大家直接行使jQuery提供的Ajax方法来把京东的首页给抓取下来,那么有如下代码:

$.ajax({
    url: 'http://www.jd.com/',
    type: 'get',
    success: function (data) {
//todo:
    }
});

但大家在浏览器上跑了这段代码之后,却开掘浏览器报了叁个荒谬:

2020欧洲杯官方投注-2020欧洲杯官方投注网址 1

本身近些日子的站点是

是因为安全的因素,浏览器会限制我们从剧本中倡导跨站央浼,所以W3C工作组退出了一种新的编写制定,即跨源能源分享(Cross-Origin Resource Sharing (CO福特ExplorerS)),这种机制让Web应用服务器能支撑跨站访谈控制,进而使得安全地进行跨站数据传输成为或许。而“Access-Control-Allow-Origin”就是该机制里面所定义的字段。W3C上有对该字段的可信定义:

2020欧洲杯官方投注-2020欧洲杯官方投注网址 2

上边说,该响应头决定三个资源是不是足以被分享给央浼头里面包车型客车“Origin”字段的值。那“Origin”是如何?我们再看看从前的Ajax供给头消息,里面确实有“Origin”字段:

2020欧洲杯官方投注-2020欧洲杯官方投注网址 3

央求头里面包车型地铁“Origin”字段的值正是自家当下的站点地址,作者是从“

由于本人改不了京东的响应头“Access-Control-Allow-Origin”字段,所以小编就融洽建了三个新的站点来测量试验一下。

站点“

$.ajax({
    url: 'http://localhost:6408/index.ashx',
    type: 'get',
    success: function (data) {
        alert(data);
    }
});

站点“

publicvoid ProcessRequest(HttpContext context)
{
    context.Response.ContentType = "text/plain";
    context.Response.Headers.Add("Access-Control-Allow-Origin", "http://localhost:6404");
    context.Response.Write(String.Format("我是站点:{0}", "http://localhost:6408"));
}

然后,大家在浏览器上跑一下,得如下结果:

2020欧洲杯官方投注-2020欧洲杯官方投注网址 4

从结果上得以看出,跨站点诉求已经成功。接下来,大家把响应头里面包车型客车“Access-Control-Allow-Origin”字段去掉:

publicvoid ProcessRequest(HttpContext context)
{
    context.Response.ContentType = "text/plain";
//context.Response.Headers.Add("Access-Control-Allow-Origin", "http://localhost:6404");
    context.Response.Write(String.Format("我是站点:{0}", "http://localhost:6408"));
}

接下来看一下结实:

2020欧洲杯官方投注-2020欧洲杯官方投注网址 5

结果果然跟此前的是一致的,这也印证了“Access-Control-Allow-Origin”在跨站点央求里面扮演的要紧剧中人物。

就算难题消除了,不过新的难点又来了,如若本身有一千个站点都要用到跨站点诉求,那么笔者难道要把这一千个站点都加到响应头里面?所以,那早晚是非常的,那么作者哪些在不改换响应头的意况下跌成跨站点央求呢?

眼下说过,导致那么些标题标直接原因是出于“浏览器限制了笔者们的本子”,那么这里就有五个前提,一个是浏览器,叁个是本子,假如我们能躲避中间四个,是否即可达成跨站点乞求呢?于是笔者就悟出了在后台代码里面一贯创设Http诉求代理来干掉浏览器。

出于直接行使HttpWebRequest类要布局的东西太多,何况在异步API那块写起来太烦琐,所以自身利用了三个轻量但成效强大的HttpClient类来落到实处这一效用。

第一,咱们来统一打算前端脚本API,为了越来越好的包容性,作者不筹算重新写套Ajax央浼的API,而是继续使用$.ajax(),只然则传递的参数分化等而已。所以,就有了上边那些脚本API:

$.ajax({
    //这个url就是代理的地址,这个地址我们可以自己去web.config中配置
    url: '/cors', 
    type: 'get',
    data: {
//no是我们自定义的参数
"no": "001",
//authkey是访问代理所需要提供的授权key,这个参数是必需的
"authkey": "e4f58a805a6e1fd0f6bef58c86f9ceb3",
//target是是告诉代理,要把我们自定义的数据提交到哪个地址,这个参数是必需的
"target": "http://localhost:6408/index.ashx"
    },
    success: function (data) {
        alert(data);
    }
});

那样一来,小编能够在细微退换下完结跨站点伏乞。

一切需要进程能够经过下图来表示:

2020欧洲杯官方投注-2020欧洲杯官方投注网址 6

下一场再来讲说 “/cors”那个地方是怎么来的,那个地址就是代理管理程序的地方,大家得以在Web.config文件之中的节点里举办安顿:

  <system.webServer>
    <handlers>
      <addname="cors"path="/cors"allowPathInfo="true"verb="GET"type="ChuXin.Web.Cors.RequestDispatcher,ChuXin.Web"/>
    </handlers>
  </system.webServer>

内部,ChuXin.Web.Cors.RequestDispatcher为代理管理程序类,其基本达成代码如下:

publicvoid Process(String target, String authkey, IReadOnlyDictionary<String,String> args = null)
{
//拼接到目标站点的请求Url
var argList = from t0 in args
select t0.Key   "="   t0.Value;
String url = String.Format("{0}?{1}", target, String.Join("&", argList));

HttpClient hc = newHttpClient();
HttpContext context = HttpContext.Current;
Object result = null;

//使用HttpClient发起异步请求
    hc.GetAsync(url, HttpCompletionOption.ResponseContentRead).ContinueWith(t =>
    {
//异步请求结束后判断是否有异常或错误
if (HasExceptions<HttpResponseMessage>(t, context)) { return; }

//如果任务正常完成
if (t.IsCompleted) {
//获取响应消息对象
var respMessage = t.Result;
if (respMessage != null && respMessage.Content != null) {
//获取目标站点响应头的Content-Type属性,并赋值给当前代理的响应头
var contentTypes = respMessage.Content.Headers.GetValues("Content-Type");
                context.Response.ContentType = String.Concat(contentTypes);
String contentType = null;
foreach (var ct in contentTypes) {
String[] parts = ct.Split(newChar[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length > 0) { contentType = parts[0].Trim(); }
                }
if (contentType.StartsWith("text/")) {
//如果content-type为文本类型的,则先以异步方式读取二进制数据,
//然后转成UTF8编码字符串赋值给结果对象
                    respMessage.Content.ReadAsByteArrayAsync().ContinueWith(t1 =>
                    {
if (HasExceptions<Byte[]>(t1, context)) { return; }

if (t1.IsCompleted) {
                            result = Encoding.UTF8.GetString(t1.Result);
                        }
                    }).Wait();
                }
else {
//如果content-type为非文本类型的,则直接以异步方式读取并赋值给结果对象
                    respMessage.Content.ReadAsByteArrayAsync().ContinueWith(t1 =>
                    {
if (HasExceptions<Byte[]>(t1, context)) { return; }

if (t1.IsCompleted) {
                            result = t1.Result;
                        }
                    }).Wait();
                }
            }
        }
    }).Wait();
//如果结果为字符串,则直接输出
if (result isString) {
        context.Response.Write(result);
    }
//如果结果为二进制数据,则写入到输出流里面
if (result isByte[]) {
var outputStream = context.Response.OutputStream;
if (outputStream.CanWrite) {
var data = result asByte[];
            outputStream.Write(data, 0, data.Length);
        }
    }
}

中间,HasExceptions()方法为自家自定义的多少个甩卖职责战败的动静的法子。

我们在浏览器里面跑一向下探底视,获得下图结果:

2020欧洲杯官方投注-2020欧洲杯官方投注网址 7

从上海体育地方看出,大家着想成功实现了。大家把需要头和响应头的详细音信调出来看看:

请求头:

2020欧洲杯官方投注-2020欧洲杯官方投注网址 8

响应头:

2020欧洲杯官方投注-2020欧洲杯官方投注网址 9 2020欧洲杯官方投注-2020欧洲杯官方投注网址 10

跨站点Get须求数据试验成功,那么跨站点文件上传呢?

我们开采HttpClient类有Post格局的哀告,例如PostAsync(String, HttpContent)方法,第贰个参数幸亏明白,那第3个参数HttpContent是吗玩意儿呢?转到定义发掘它是三个抽象类,于是乎小编就想明白有啥样子类达成了它,于是张开反编写翻译工具大家开掘有下面多少个类完结了它:

2020欧洲杯官方投注-2020欧洲杯官方投注网址 11

经过反编写翻译工具,大家来看“FormUrlEncodedContent”类的陈说为“A container for name/value tuples encoded using application/x-www-form-urlencoded MIME type.”,所以它是适用于“application/x-www-form-urlencoded”那连串型的,很分明文件不属于这种,StringContent同样不合乎。然后大家再看看“MultipartFormDataContent”类,它的叙说为“Provides a container for content encoded using multipart/form-data MIME type.”,眼尖的同班确定已经开掘了,它就是跟咱们上传文件所需的MIME类型一致的类了,所以大家就利用它来封装大家要上传的文书数量。

为此基本代码如下:

publicvoid ProcessRequest(HttpContext context)
{
//获取目标站点地址
String target = context.Request.Unvalidated["target"];
if (String.IsNullOrWhiteSpace(target)) { return; }
    target = HttpUtility.UrlDecode(target);

HttpClient client = newHttpClient();

//定义请求的边界值
String boundary = String.Format("-------ChuXinWebBoundary{0}", DateTime.Now.Ticks.ToString("x"));
//将多个文件添加到请求的主内容里面
var content = newMultipartFormDataContent(boundary);
var files = context.Request.Files;
for (Int32 i = 0; i < files.Count; i  ) {
var file = files[i];
var buf = newByte[file.InputStream.Length];
if (file.InputStream.Read(buf, 0, buf.Length) > 0) {
//创建一个二进制内容对象
var dataContent = newByteArrayContent(buf, 0, buf.Length);
//指定该对象的Content-Type
            dataContent.Headers.Add("Content-Type", file.ContentType);
//添加到请求主内容里面
            content.Add(dataContent, "file"   i, file.FileName);
        }
    }

//将form表单数据添加的主内容对象里面
var form = context.Request.Form;
foreach (var key in form.AllKeys) {
if (String.Compare(key, "target", true) == 0) { continue; }
var data = Encoding.UTF8.GetBytes(form[key]);
var dataContent = newByteArrayContent(data);
        content.Add(dataContent, key);
    }

String result = null;
//执行异步POST提交请求
    client.PostAsync(target, content).ContinueWith(t0 =>
    {
if (t0.IsCompleted) {
var respMessage = t0.Result;
if (respMessage != null && respMessage.Content != null) {
//请求完成后,异步读取目标站点的响应结果信息
                respMessage.Content.ReadAsStringAsync().ContinueWith(t1 =>
                {
if (t1.IsCompleted) {
                        result = t1.Result;
                    }
                }).Wait();
            }
        }
    }).Wait();
//获取到响应结果信息后输出
    context.Response.Write(result);
    client.Dispose();
}

下一场我们测量检验一下:

率先,诉求发起站点(

<formaction="/cors"method="post"enctype="multipart/form-data">
<inputname="myfile"type="file"/><br/><br/>
<inputname="authkey"type="hidden"value="e4f58a805a6e1fd0f6bef58c86f9ceb3"/>
<inputname="target"type="hidden"value="http://localhost:6408/file/upload"/>
<inputname="dir"type="hidden"value="~/uploaddir/"/>
<inputtype="submit"value="提交"/>
</form>

然后,在伸手发起站点的web.config文件中配备代理:

<system.webServer>
  <handlers>
    <addname="cors"path="/cors"verb="GET,POST"type="ChuXin.Web.Cors.RequestDispatcher,ChuXin.Web"/>
  </handlers>
</system.webServer>

提及底选个公文提交一把,得如下结果:

2020欧洲杯官方投注-2020欧洲杯官方投注网址 12

以此正是本身上传的图纸文件地方,它已成功上传到“

参谋文献

正文永世更新链接地址:

在做Web系统的时候,大家平日会采取Ajax工夫来贯彻异步加载数据的效果与利益,发轫的时候我们的系...

本文由2020欧洲杯官方投注-2020欧洲杯官方投注网址发布于win7,转载请注明出处:2020欧洲杯官方投注-2020欧洲杯官方投注网址应用

关键词: 欧洲杯外围

上一篇:至于Zabbix一些高等功用

下一篇:没有了

最火资讯