麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發設計 > 正文

WebApi系列~在WebApi中實現Cors訪問

2019-11-15 02:31:05
字體:
來源:轉載
供稿:網友

WebApi系列~在WebApi中實現Cors訪問

回到目錄

說在前

Cors是個比較熱的技術,這在蔣金楠的博客里也有體現,Cors簡單來說就是“跨域資源訪問”的意思,這種訪問我們指的是Ajax實現的異步訪問,形象點說就是,一個A網站公開一些接口方法,對于B網站和C網站可以通過發xmlhttPRequest請求來調用A網站的方法,對于xmlhttprequest封裝比較好的插件如jquery的$.ajax,它可以讓開發者很容易的編寫AJAX異步請求,無論是Get,Post,Put,Delete請求都可以發送。

Cors并不是什么新的技術,它只是對HTTP請求頭進行了一個加工,還有我們的Cors架構里,對jsonp也有封裝,讓開發者在使用jsonp訪問里,編寫的代碼量更少,更直觀,呵呵。(Jsonp和Json沒什么關系,它是從一個URI返回一個Script響應塊,所以,JSONP本身是和域名沒關系的,而傳統上的JSON是走xmlhttprequest的,它在默認情況下,是不能跨域訪問的)

做在后

一  下面先說一下,對jsonp的封裝

1 注冊jsonp類型,在global.asax里application_Start方法中

 GlobalConfiguration.Configuration.Formatters.Insert(0, new EntityFrameworks.Web.Core.JsonpMediaTypeFormatter());

2 編寫JsonpMediaTypeFormatter這個類型中實現了對jsonp請求的響應,并在響應流中添加指定信息,如callback方法名。

 /// <summary>    /// 對jsonp響應流的封裝    /// </summary>    public class JsonpMediaTypeFormatter : JsonMediaTypeFormatter    {        public string Callback { get; private set; }        public JsonpMediaTypeFormatter(string callback = null)        {            this.Callback = callback;        }        public override Task WriteToStreamAsync(            Type type,            object value,            Stream writeStream,            HttpContent content,            TransportContext transportContext)        {            if (string.IsNullOrEmpty(this.Callback))            {                return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);            }            try            {                this.WriteToStream(type, value, writeStream, content);                return Task.FromResult<AsyncVoid>(new AsyncVoid());            }            catch (Exception exception)            {                TaskCompletionSource<AsyncVoid> source = new TaskCompletionSource<AsyncVoid>();                source.SetException(exception);                return source.Task;            }        }        private void WriteToStream(            Type type,            object value,            Stream writeStream,            HttpContent content)        {            JsonSerializer serializer = JsonSerializer.Create(this.SerializerSettings);            using (StreamWriter streamWriter = new StreamWriter(writeStream, this.SupportedEncodings.First()))            using (JsonTextWriter jsonTextWriter = new JsonTextWriter(streamWriter) { CloSEOutput = false })            {                jsonTextWriter.WriteRaw(this.Callback + "(");                serializer.Serialize(jsonTextWriter, value);                jsonTextWriter.WriteRaw(")");            }        }        public override MediaTypeFormatter GetPerRequestFormatterInstance(            Type type,            HttpRequestMessage request,            MediaTypeHeaderValue mediaType)        {            if (request.Method != HttpMethod.Get)            {                return this;            }            string callback;            if (request.GetQueryNameValuePairs().ToDictionary(pair => pair.Key,                 pair => pair.Value).TryGetValue("callback", out callback))            {                return new JsonpMediaTypeFormatter(callback);            }            return this;        }        [StructLayout(LayoutKind.Sequential, Size = 1)]        private struct AsyncVoid        {        }    }

二  對指定域名實現友好的跨域資源訪問

1 在global.asax中注冊這個HttpHandler,使它對HTTP的處理進行二次加工,它可以有同步和異步兩個版本,本例中實現異步方式實現

 //對指定URI的網站進行跨域資源的共享 GlobalConfiguration.Configuration.MessageHandlers.Add(new EntityFrameworks.Web.Core.Handlers.CorsMessageHandler());

下面是MessageHandlers原代碼,實現對HTTP請求的二次處理

    /// <summary>    /// 跨域資源訪問的HTTP處理程序    /// </summary>    public class CorsMessageHandler : DelegatingHandler    {        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)        {            //得到描述目標Action的HttpActionDescriptor            HttpMethod originalMethod = request.Method;            bool isPreflightRequest = request.IsPreflightRequest();            if (isPreflightRequest)            {                string method = request.Headers.GetValues("access-Control-Request-Method").First();                request.Method = new HttpMethod(method);            }            HttpConfiguration configuration = request.GetConfiguration();            HttpControllerDescriptor controllerDescriptor = configuration.Services.GetHttpControllerSelector().SelectController(request);            HttpControllerContext controllerContext = new HttpControllerContext(request.GetConfiguration(), request.GetRouteData(), request)            {                ControllerDescriptor = controllerDescriptor            };            HttpActionDescriptor actionDescriptor = configuration.Services.GetActionSelector().SelectAction(controllerContext);            //根據HttpActionDescriptor得到應用的CorsAttribute特性            CorsAttribute corsAttribute = actionDescriptor.GetCustomAttributes<CorsAttribute>().FirstOrDefault() ??                controllerDescriptor.GetCustomAttributes<CorsAttribute>().FirstOrDefault();            if (null == corsAttribute)            {                return base.SendAsync(request, cancellationToken);            }            //利用CorsAttribute實施授權并生成響應報頭            IDictionary<string, string> headers;            request.Method = originalMethod;            bool authorized = corsAttribute.TryEvaluate(request, out headers);            HttpResponseMessage response;            if (isPreflightRequest)            {                if (authorized)                {                    response = new HttpResponseMessage(HttpStatusCode.OK);                }                else                {                    response = request.CreateErrorResponse(HttpStatusCode.BadRequest, corsAttribute.ErrorMessage);                }            }            else            {                response = base.SendAsync(request, cancellationToken).Result;            }            //添加響應報頭            if (headers != null && headers.Any())                foreach (var item in headers)                    response.Headers.Add(item.Key, item.Value);            return Task.FromResult<HttpResponseMessage>(response);        }    }

2 添加Cors特性,以便處理可以跨域訪問的域名,如B網站和C網站

    /// <summary>    /// Cors特性    /// </summary>   [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)]       public class CorsAttribute : Attribute    {        public Uri[] AllowOrigins { get; private set; }        public string ErrorMessage { get; private set; }        public CorsAttribute(params string[] allowOrigins)        {            this.AllowOrigins = (allowOrigins ?? new string[0]).Select(origin => new Uri(origin)).ToArray();        }        public bool TryEvaluate(HttpRequestMessage request, out IDictionary<string, string> headers)        {            headers = null;            string origin = null;            try            {                origin = request.Headers.GetValues("Origin").FirstOrDefault();            }            catch (Exception)            {                this.ErrorMessage = "Cross-origin request denied";                return false;            }            Uri originUri = new Uri(origin);            if (this.AllowOrigins.Contains(originUri))            {                headers = this.GenerateResponseHeaders(request);                return true;            }            this.ErrorMessage = "Cross-origin request denied";            return false;        }        private IDictionary<string, string> GenerateResponseHeaders(HttpRequestMessage request)        {            //設置響應頭"Access-Control-Allow-Methods"            string origin = request.Headers.GetValues("Origin").First();            Dictionary<string, string> headers = new Dictionary<string, string>();            headers.Add("Access-Control-Allow-Origin", origin);            if (request.IsPreflightRequest())            {                //設置響應頭"Access-Control-Request-Headers"                //和"Access-Control-Allow-Headers"                headers.Add("Access-Control-Allow-Methods",
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 国产乱子视频 | 久久精品艹 | 国产午夜电影在线观看 | 欧美a∨一区二区三区久久黄 | 超碰97人| 毛片中文字幕 | 激情视频导航 | 成人区精品一区二区婷婷 | 久久久久久免费 | 97超级碰碰人国产在线观看 | 极品销魂一区二区三区 | 黄色一级片在线免费观看 | 成人免费乱码大片a毛片视频网站 | 免费看欧美黑人毛片 | 热re91久久精品国产99热 | 国产免费观看视频 | 欧美激情区 | 欧美日本不卡 | 91麻豆精品国产91久久久点播时间 | 精品国产一区二区久久 | 激情av在线 | 高颜值美女啪啪 | 久久影片| 成年免费网站 | 国产91一区二区三区 | 国产一级毛片国产 | 久久免费综合视频 | 国产三级在线观看a | 国产91一区 | 91丝袜 | 久久久中 | 一级黄色毛片播放 | 久久久麻豆 | 国产一级一区二区三区 | 国产一区二区亚洲 | 婷婷久久网 | 91美女啪啪 | 久草在线观看福利 | 羞羞电影网 | 国产羞羞视频在线观看 | 大号bbwassbigav头交 |