WebApi Ajax 跨域请求解决方法(CORS实现)(作者:jianxuanbing)
概述
ASP.NET Web API 的好用使用过的都知道,没有复杂的配置文件,一个简单的ApiController加上需要的Action就能工作。但是在使用API的时候总会遇到跨域请求的问题,
特别各种APP万花齐放的今天,API的跨域请求是不能避免的。
在默认情况下,为了防止CSRF跨站的伪造攻击(或者是 javascript的同源策略(Same-Origin Policy)),一个网页从另外一个域获取数据时就会收到限制。有一些方法可以突破这个限制,那就是大家熟知的JSONP, 当然这只是众多解决方法中一种,由于JSONP只支持GET的请求,如今的复杂业务中已经不能满足需求。而CORS(Cross Origin Resource Sharing https://www.w3.org/wiki/CORS)跨域资源共享,是一种新的header规范,可以让服务器端放松跨域的限制,可以根据header来切换限制或者不限制跨域请求。重要的是它支持所有http请求方式。
问题
XMLHttpRequest 跨域 POST或GET请求 ,请求方式会自动变成OPTIONS的问题。
由于CORS(cross origin resource share)规范的存在,浏览器会首先发送一次options嗅探,同时header带上origin,判断是否有跨域请求权限,服务器响应access control allow origin的值,供浏览器与origin匹配,如果匹配则正式发送post请求,即便是服务器允许程序跨域访问,若不支持 options 请求,请求也会死掉。
原因
浏览器为了安全起见,会Preflighted Request的透明服务器验证机制支持开发人员使用自定义的头部、GET或POST之外的方法,以及不同类型的主题内容,也就是会先发送一个 options 请求,
问问服务器是否会正确(允许)请求,确保请求发送是安全的。
出现 OPTIONS 的情况一般为:
1、非GET 、POST请求
2、POST请求的content-type不是常规的三个:application/x- www-form-urlencoded(使用 HTTP 的 POST 方法提交的表单)、multipart/form-data(同上,但主要用于表单提交时伴随文件上传的场合)、text/plain(纯文本)
3、POST请求的payload为text/html
4、设置自定义头部
OPTIONS请求头部中会包含以下头部:Origin、Access-Control-Request-Method、Access-Control-Request-Headers,发送这个请求后,服务器可以设置如下头部与浏览器沟通来判断是否允许这个请求。
Access-Control-Allow-Origin、Access-Control-Allow-Method、Access-Control-Allow-Headers
解决方法
此方法功能强大,可以解决ASP.NET Web API复杂跨域请求,携带复杂头部信息,正文内容和授权验证信息
方法一
public class CrosHandler:DelegatingHandler
{
private const string Origin = "Origin";
private const string AccessControlRequestMethod = "Access-Control-Request-Method";
private const string AccessControlRequestHeaders = "Access-Control-Request-Headers";
private const string AccessControlAllowOrign = "Access-Control-Allow-Origin";
private const string AccessControlAllowMethods = "Access-Control-Allow-Methods";
private const string AccessControlAllowHeaders = "Access-Control-Allow-Headers";
private const string AccessControlAllowCredentials = "Access-Control-Allow-Credentials";
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
bool isCrosRequest = request.Headers.Contains(Origin);
bool isPrefilightRequest = request.Method == HttpMethod.Options;
if (isCrosRequest)
{
Task<HttpResponseMessage> taskResult = null;
if (isPrefilightRequest)
{
taskResult = Task.Factory.StartNew<HttpResponseMessage>(() =>
{
HttpResponseMessage response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
response.Headers.Add(AccessControlAllowOrign,
request.Headers.GetValues(Origin).FirstOrDefault());
string method = request.Headers.GetValues(AccessControlRequestMethod).FirstOrDefault();
if (method != null)
{
response.Headers.Add(AccessControlAllowMethods, method);
}
string headers = string.Join(", ", request.Headers.GetValues(AccessControlRequestHeaders));
if (!string.IsNullOrWhiteSpace(headers))
{
response.Headers.Add(AccessControlAllowHeaders, headers);
}
response.Headers.Add(AccessControlAllowCredentials, "true");
return response;
}, cancellationToken);
}
else
{
taskResult = base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>(t =>
{
var response = t.Result;
response.Headers.Add(AccessControlAllowOrign,
request.Headers.GetValues(Origin).FirstOrDefault());
response.Headers.Add(AccessControlAllowCredentials, "true");
return response;
});
}
return taskResult;
}
return base.SendAsync(request, cancellationToken);
}
}
使用方式,在Global.asax文件添加
protected void Application_Start()
{
IOCConfig.RegisterAll();
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
GlobalConfiguration.Configuration.MessageHandlers.Add(new CrosHandler());
}
方法二
配置文件中添加如下配置,此方法简单,应对简单的跨域请求
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST,OPTIONS" />
</customHeaders>
</httpProtocol>
<system.webServer>
参考文献
https://code.msdn.microsoft.com/windowsdesktop/Implementing-CORS-support-a677ab5d#content
WebApi Ajax 跨域请求解决方法(CORS实现)(作者:jianxuanbing)的更多相关文章
- WebApi Ajax 跨域请求解决方法(CORS实现)
概述 ASP.NET Web API 的好用使用过的都知道,没有复杂的配置文件,一个简单的ApiController加上需要的Action就能工作.但是在使用API的时候总会遇到跨域请求的问题, 特别 ...
- 第114天:Ajax跨域请求解决方法(二)
一.什么是跨域 我们先回顾一下域名地址的组成: http:// www . google : 8080 / script/jquery.js http:// (协议号) www (子 ...
- 第113天:Ajax跨域请求解决方法
一.原生JS实现ajax 第一步获得XMLHttpRequest对象 第二步:设置状态监听函数 第三步:open一个连接,true是异步请求 第四部:send一个请求,可以发送一个对象和字符串,不需要 ...
- Access to XMLHttpRequest at 'XXX' from origin 'XX' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present o AJAX跨域请求解决方法
今天出现了一个问题找了好久先看代码: 这可能是个BUG吧插入代码: dataType: 'jsonp', crossDomain: true, 最终:
- Nginx反向代理、CORS、JSONP等跨域请求解决方法总结
由于 Javascript 同源策略的存在使得一个源中加载来自其它源中资源的行为受到了限制.即会出现跨域请求禁止. 通俗一点说就是如果存在协议.域名.端口或者子域名不同服务端,或一者为IP地址,一者为 ...
- 客户端ajax请求为实现Token验证添加headers后导致正常请求变为options跨域请求解决方法
客户端为了实现token认证,通过Jquery的ajaxSetup方法全局配置headers: 全局配置headers后会导致部分不需要token认证的请求变为options请求,导致跨域访问.报错信 ...
- 基于.Net Framework 4.0 Web API开发(5):ASP.NET Web APIs AJAX 跨域请求解决办法(CORS实现)
概述: ASP.NET Web API 的好用使用过的都知道,没有复杂的配置文件,一个简单的ApiController加上需要的Action就能工作.但是在使用API的时候总会遇到跨域请求的问题,特 ...
- express 请求跨域后端解决方法CORS
CORS全称Cross-Origin Resource Sharing,是HTML5规范定义的如何跨域访问资源. Origin表示本域,也就是浏览器当前页面的域.当JavaScript向外域(如sin ...
- Ajax跨域请求action方法,无法传递及接收cookie信息(应用于系统登录认证及退出)解决方案
最近的项目中涉及到了应用ajax请求后台系统登录,身份认证失败,经过不断的调试终于找到解决方案. 应用场景: 项目测试环境:前端应用HTML,js,jQuery ajax请求,部署在Apache服务器 ...
随机推荐
- 测试环境-memcached安装与说明
一,下载memcached和libevent安装包: 1,Memcache用到了libevent这个库用于Socket的处理,所以还需要安装libevent (这两个包百度上都能找到) 二,安装lib ...
- Js 获取时间戳
//获取时间戳 单位:秒: //1. 获取当前时间戳 function getUnixTime(){ var date = new Date(); //使用getTime方法: var unix_ti ...
- docker - 设置HTTP/HTTPS 代理
背景 将docker的服务器环境切换到新的网络之后,由于服务器的internet是受限制的(需要连接配置远程代理,不能直接上网).因此,在使用docker连接docker hub 的时候,就会出错: ...
- iOS上机题(附个人见解)
##机试题目如下 用命令行创建一个以CocoaPods管理的项目[Test-你的姓名拼音],新建3个ViewController,完成以下题目 将下面的问题在一个UITabView里面列出所有问题,单 ...
- NYOJ--1276--机器设备(河南省第九届省赛,简单的bfs)
机器设备 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 Alpha 公司设计出一种节能的机器设备.它的内部结构是由 N 个齿轮组成.整个机器设备有 一个驱动齿轮,当 ...
- hdu--1421--dp--搬寝室
注意:dp[i][j]初始化的时候不能小于0xffffff明显大于2^15但是吧再小就WA了 #include<iostream> #include<algorithm> #i ...
- ecshop中的些assign_dynamic(’')
很多做电子商务站的朋友都问我,在ecshop中,里面有个 assign_dynamic('index');这个到底是什么作用来的,这个其实是ecshop中的模板技术,动态处理一些局部信息更新而不被缓存 ...
- [原创] Python3.6+request+beautiful 半次元Top100 爬虫实战,将小姐姐的cos美图获得
1 技术栈 Python3.6 Python的版本 request 得到网页html.jpg等资源的lib beautifulsoup 解析html的利器 html5lib 指定beautifulso ...
- ASP.NET WebApi 使用Swagger生成接口文档
前言 公司一直采用Word文档方式与客户端进行交流.随着时间的推移,接口变的越来越多,文档变得也很繁重.而且一份文档经常由多个开发人员维护,很难保证文档的完整性.而且有时写完代码也忘了去更新文档,为了 ...
- JavaScript获取和创建元素
1.JavaScript中获取元素 常用的获取document中元素的方法: 1) document.getElementById() =>通过元素ID获取文档中特定的元素,如获取 id = ...