• WebAPI IE8、IE9 跨域问题


    关于WebAPI跨域的问题,网上已经很多了,以下方案可以解决很多跨域问题,但是都不支持IE8、IE9浏览器,JSONP也只能支持Get请求

    1. 通过dll配置 Install-Package Microsoft.AspNet.WebApi.Cors
    2. 配置 Web.config

    IE8,IE9跨域是通过XDomainRequest这个对象去实现,和XMLHttpRequest类似,可以参考下面文档

    https://msdn.microsoft.com/zh-cn/library/dd573303(v=vs.85).aspx

    使用jQuery.ajax的基础上,在jQuery下面再引用

    https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest/blob/master/jQuery.XDomainRequest.js

    这样IE8、IE9跨域成功了

            public Response<string> Post()
            {
                Response<string> rs = new Response<string>
                {
                    head = new ResponseHeader { errcode = 0, errmessage = "post" },
                    data = "hello"
                };
                return rs;
            }

    这样IE8、IE9跨域失败了

            public Response<string> Post(Request<Message> request)
            {
                Response<string> rs = new Response<string>
                {
                    head = new ResponseHeader { errcode = 0, errmessage = "post" },
                    data = request.data.content
                };
                return rs;
            }

    后来通过排查,有对象形参的WebAPI就会遇到反序列化问题,(IE8,IE9)转换为request对象的時候报错

    试了很多次,前端帶不过來Content-Type,就想到了用參数传递到后端,也修改了jQuery.XDOmainRequest.js这个文件

      1 /*!
      2  * jQuery-ajaxTransport-XDomainRequest - v1.0.4 - 2015-03-05
      3  * https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest
      4  * Copyright (c) 2015 Jason Moon (@JSONMOON)
      5  * Licensed MIT (/blob/master/LICENSE.txt)
      6  */
      7 (function (factory) {
      8     if (typeof define === 'function' && define.amd) {
      9         // AMD. Register as anonymous module.
     10         define(['jquery'], factory);
     11     } else if (typeof exports === 'object') {
     12         // CommonJS
     13         module.exports = factory(require('jquery'));
     14     } else {
     15         // Browser globals.
     16         factory(jQuery);
     17     }
     18 }(function ($) {
     19 
     20     // Only continue if we're on IE8/IE9 with jQuery 1.5+ (contains the ajaxTransport function)
     21     if ($.support.cors || !$.ajaxTransport || !window.XDomainRequest) {
     22         return $;
     23     }
     24 
     25     var httpRegEx = /^(https?:)?///i;
     26     var getOrPostRegEx = /^get|post$/i;
     27     var sameSchemeRegEx = new RegExp('^(//|' + location.protocol + ')', 'i');
     28 
     29     // ajaxTransport exists in jQuery 1.5+
     30     $.ajaxTransport('* text html xml json', function (options, userOptions, jqXHR) {
     31 
     32         // Only continue if the request is: asynchronous, uses GET or POST method, has HTTP or HTTPS protocol, and has the same scheme as the calling page
     33         if (!options.crossDomain || !options.async || !getOrPostRegEx.test(options.type) || !httpRegEx.test(options.url) || !sameSchemeRegEx.test(options.url)) {
     34             return;
     35         }
     36 
     37         var xdr = null;
     38 
     39         return {
     40             send: function (headers, complete) {
     41                 var postData = '';
     42                 var userType = (userOptions.dataType || '').toLowerCase();
     43 
     44                 xdr = new XDomainRequest();
     45                 if (/^d+$/.test(userOptions.timeout)) {
     46                     xdr.timeout = userOptions.timeout;
     47                 }
     48 
     49                 xdr.ontimeout = function () {
     50                     complete(500, 'timeout');
     51                 };
     52 
     53                 xdr.onload = function () {
     54                     var allResponseHeaders = 'Content-Length: ' + xdr.responseText.length + '
    Content-Type: ' + xdr.contentType;
     55                     var status = {
     56                         code: 200,
     57                         message: 'success'
     58                     };
     59                     var responses = {
     60                         text: xdr.responseText
     61                     };
     62                     try {
     63                         if (userType === 'html' || /text/html/i.test(xdr.contentType)) {
     64                             responses.html = xdr.responseText;
     65                         } else if (userType === 'json' || (userType !== 'text' && //json/i.test(xdr.contentType))) {
     66                             try {
     67                                 responses.json = $.parseJSON(xdr.responseText);
     68                             } catch (e) {
     69                                 status.code = 500;
     70                                 status.message = 'parseerror';
     71                                 //throw 'Invalid JSON: ' + xdr.responseText;
     72                             }
     73                         } else if (userType === 'xml' || (userType !== 'text' && //xml/i.test(xdr.contentType))) {
     74                             var doc = new ActiveXObject('Microsoft.XMLDOM');
     75                             doc.async = false;
     76                             try {
     77                                 doc.loadXML(xdr.responseText);
     78                             } catch (e) {
     79                                 doc = undefined;
     80                             }
     81                             if (!doc || !doc.documentElement || doc.getElementsByTagName('parsererror').length) {
     82                                 status.code = 500;
     83                                 status.message = 'parseerror';
     84                                 throw 'Invalid XML: ' + xdr.responseText;
     85                             }
     86                             responses.xml = doc;
     87                         }
     88                     } catch (parseMessage) {
     89                         throw parseMessage;
     90                     } finally {
     91                         complete(status.code, status.message, responses, allResponseHeaders);
     92                     }
     93                 };
     94 
     95                 // set an empty handler for 'onprogress' so requests don't get aborted
     96                 xdr.onprogress = function () { };
     97                 xdr.onerror = function () {
     98                     complete(500, 'error', {
     99                         text: xdr.responseText
    100                     });
    101                 };
    102 
    103                 if (userOptions.data) {
    104                     postData = ($.type(userOptions.data) === 'string') ? userOptions.data : $.param(userOptions.data);
    105                 }
    106                 if (options.contentType && options.contentType.length > 0) {
    107                     if (options.url.indexOf('?') > -1) {
    108                         options.url = options.url + '&_contentType=' + options.contentType;
    109                     } else {
    110                         options.url = options.url + '?_contentType=' + options.contentType;
    111                     }
    112                 }
    113                 xdr.open(options.type, options.url);
    114                 xdr.send(postData);
    115             },
    116             abort: function () {
    117                 if (xdr) {
    118                     xdr.abort();
    119                 }
    120             }
    121         };
    122     });
    123 
    124     return $;
    125 
    126 }));
    jQuery.XDomainRequest.js

    加上消息处理就可以解决

     public class CrossDomainFixIEHandler : DelegatingHandler
        {
            protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
            {
                if (request.Method == HttpMethod.Options)
                {
                    HttpResponseMessage response = request.CreateResponse<string>(HttpStatusCode.OK, null);
                    TaskCompletionSource<HttpResponseMessage> tcs = new TaskCompletionSource<HttpResponseMessage>();
                    tcs.SetResult(response);
                    return tcs.Task;
                }
                if (request.Content.Headers.ContentType == null || string.IsNullOrWhiteSpace(request.Content.Headers.ContentType.MediaType))
                {
                    string contentType = this.GetContentType(string.Concat(request.RequestUri.Query, "&"));
                    if (string.IsNullOrWhiteSpace(contentType))
                    {
                        contentType = "application/json";
                    }
                    request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
                }
                return base.SendAsync(request, cancellationToken);
            }
    
            /// <summary>
            /// 獲取ContentType
            /// </summary>
            /// <param name="source"></param>
            /// <returns></returns>
            private string GetContentType(string source)
            {
                if (string.IsNullOrWhiteSpace(source))
                {
                    return string.Empty;
                }
                Regex regex = new Regex("[&?]_contentType=(?<contentType>(.*?))&", RegexOptions.IgnoreCase);
                Match match = regex.Match(source);
                if (match.Success)
                {
                    return match.Groups["contentType"].Value;
                }
                else
                {
                    return string.Empty;
                }
            }

  • 相关阅读:
    略少面试题 项目中用到的技术详解 有用
    python在VM+centos7 下面的安装
    shell基础09 归档数据
    shell基础10 sed,gawk和shell的对比
    shell练习03 mysql在脚本中的使用
    shell练习03 安装mysql
    shell基础09 gawk程序(上)
    shell练习02 归档数据文件
    shell基础08 sed命令行编辑器(上)
    shell基础07 函数
  • 原文地址:https://www.cnblogs.com/cmsdn/p/5960670.html
Copyright © 2020-2023  润新知