WebAPI IE8、IE9 跨域问题
2016-10-14 16:55
183 查看
关于WebAPI跨域的问题,网上已经很多了,以下方案可以解决很多跨域问题,但是都不支持IE8、IE9浏览器,JSONP也只能支持Get请求
通过dll配置 Install-Package Microsoft.AspNet.WebApi.Cors
配置 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跨域成功了
这样IE8、IE9跨域失败了
后来通过排查,有对象形参的WebAPI就会遇到反序列化问题,(IE8,IE9)转换为request对象的時候报错
试了很多次,前端帶不过來Content-Type,就想到了用參数传递到后端,也修改了jQuery.XDOmainRequest.js这个文件
jQuery.XDomainRequest.js
加上消息处理就可以解决
完
通过dll配置 Install-Package Microsoft.AspNet.WebApi.Cors
配置 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这个文件
/*! * jQuery-ajaxTransport-XDomainRequest - v1.0.4 - 2015-03-05 * https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest * Copyright (c) 2015 Jason Moon (@JSONMOON) * Licensed MIT (/blob/master/LICENSE.txt) */ (function (factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as anonymous module. define(['jquery'], factory); } else if (typeof exports === 'object') { // CommonJS module.exports = factory(require('jquery')); } else { // Browser globals. factory(jQuery); } }(function ($) { // Only continue if we're on IE8/IE9 with jQuery 1.5+ (contains the ajaxTransport function) if ($.support.cors || !$.ajaxTransport || !window.XDomainRequest) { return $; } var httpRegEx = /^(https?:)?\/\//i; var getOrPostRegEx = /^get|post$/i; var sameSchemeRegEx = new RegExp('^(\/\/|' + location.protocol + ')', 'i'); // ajaxTransport exists in jQuery 1.5+ $.ajaxTransport('* text html xml json', function (options, userOptions, jqXHR) { // 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 if (!options.crossDomain || !options.async || !getOrPostRegEx.test(options.type) || !httpRegEx.test(options.url) || !sameSchemeRegEx.test(options.url)) { return; } var xdr = null; return { send: function (headers, complete) { var postData = ''; var userType = (userOptions.dataType || '').toLowerCase(); xdr = new XDomainRequest(); if (/^\d+$/.test(userOptions.timeout)) { xdr.timeout = userOptions.timeout; } xdr.ontimeout = function () { complete(500, 'timeout'); }; xdr.onload = function () { var allResponseHeaders = 'Content-Length: ' + xdr.responseText.length + '\r\nContent-Type: ' + xdr.contentType; var status = { code: 200, message: 'success' }; var responses = { text: xdr.responseText }; try { if (userType === 'html' || /text\/html/i.test(xdr.contentType)) { responses.html = xdr.responseText; } else if (userType === 'json' || (userType !== 'text' && /\/json/i.test(xdr.contentType))) { try { responses.json = $.parseJSON(xdr.responseText); } catch (e) { status.code = 500; status.message = 'parseerror'; //throw 'Invalid JSON: ' + xdr.responseText; } } else if (userType === 'xml' || (userType !== 'text' && /\/xml/i.test(xdr.contentType))) { var doc = new ActiveXObject('Microsoft.XMLDOM'); doc.async = false; try { doc.loadXML(xdr.responseText); } catch (e) { doc = undefined; } if (!doc || !doc.documentElement || doc.getElementsByTagName('parsererror').length) { status.code = 500; status.message = 'parseerror'; throw 'Invalid XML: ' + xdr.responseText; } responses.xml = doc; } } catch (parseMessage) { throw parseMessage; } finally { complete(status.code, status.message, responses, allResponseHeaders); } }; // set an empty handler for 'onprogress' so requests don't get aborted xdr.onprogress = function () { }; xdr.onerror = function () { complete(500, 'error', { text: xdr.responseText }); }; if (userOptions.data) { postData = ($.type(userOptions.data) === 'string') ? userOptions.data : $.param(userOptions.data); } if (options.contentType && options.contentType.length > 0) { if (options.url.indexOf('?') > -1) { options.url = options.url + '&_contentType=' + options.contentType; } else { options.url = options.url + '?_contentType=' + options.contentType; } } xdr.open(options.type, options.url); xdr.send(postData); }, abort: function () { if (xdr) { xdr.abort(); } } }; }); return $; }));
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; } }
完
相关文章推荐
- IE9 IE8 ajax跨域问题的解决
- IE9 IE8 Ajax跨域问题
- 解决IE9 IE8的跨域 请求问题
- IE9 IE8 ajax跨域问题的快速解决方法
- 一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10
- 一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10
- Div+CSS浏览器兼容问题( FireFox IE6 IE7 IE8 IE9)
- 一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10
- 一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10
- IE9版本以下ajax 跨域问题可行解决方法
- ie6,ie7,ie8,ie9,firefox兼容问题
- 一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10
- IE9版本以下ajax 跨域问题可行解决方法
- 解决firefox和IE9对icon font字体的跨域访问问题
- IE10,IE9,IE8等出现控件的click不能触发的问题,罪魁祸首竟然是腾讯
- 解决firefox和IE9对icon font字体的跨域访问问题
- IE6、IE7、IE8、IE9、Firefox兼容性问题总结
- 一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10
- 【浏览器兼容性】一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10
- Win 7 卸载 IE9 到 IE8 问题解决方案!