基于CORS实现WebApi Ajax 跨域请求解决方法

发布时间 - 2026-01-11 02:43:08    点击率:

概述

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>

总结

以上所述是小编给大家介绍的基于CORS实现WebApi Ajax 跨域请求解决方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


# ajax  # 跨域请求  # webapi  # Apache中配置支持CORS(跨域资源共享)实例  # 跨域资源共享 CORS 详解  # 浅析jsopn跨域请求原理及cors(跨域资源共享)的完美解决方法  # JS跨域解决方案之使用CORS实现跨域  # js实现跨域的几种方法汇总(图片ping、JSONP和CORS)  # 跨域请求的完美解决方法(JSONP  # CORS)  # 跨域请求两种方法 jsonp和cors的实现  # 你可能不知道的CORS跨域资源共享  # 解决方法  # 自定义  # 表单  # 小编  # 配置文件  # 的是  # 判断是否  # 是一种  # 也会  # 就能  # 在此  # 给大家  # 或者是  # 这只  # 总会  # 时就  # 另外一个  # 好用  # 可以根据  # 主要用于 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 宙斯浏览器文件分类查看教程 快速筛选视频文档与图片方法  iOS中将个别页面强制横屏其他页面竖屏  JS碰撞运动实现方法详解  Laravel如何部署到服务器_线上部署Laravel项目的完整流程与步骤  Laravel如何使用Service Provider服务提供者_Laravel依赖注入与容器绑定【深度】  JavaScript如何操作视频_媒体API怎么控制播放  php嵌入式断网后怎么恢复_php检测网络重连并恢复硬件控制【操作】  零服务器AI建站解决方案:快速部署与云端平台低成本实践  Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?  开心动漫网站制作软件下载,十分开心动画为何停播?  如何解决hover在ie6中的兼容性问题  Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道  Laravel如何使用软删除(Soft Deletes)功能_Eloquent软删除与数据恢复方法  如何用已有域名快速搭建网站?  高端云建站费用究竟需要多少预算?  html5怎么画眼睛_HT5用Canvas或SVG画眼球瞳孔加JS控制动态【绘制】  Laravel如何实现数据导出到CSV文件_Laravel原生流式输出大数据量CSV【方案】  Laravel如何实现用户密码重置功能?(完整流程代码)  香港网站服务器数量如何影响SEO优化效果?  Win11关机界面怎么改_Win11自定义关机画面设置【工具】  如何获取上海专业网站定制建站电话?  Firefox Developer Edition开发者版本入口  laravel怎么用DB facade执行原生SQL查询_laravel DB facade原生SQL执行方法  网站页面设计需要考虑到这些问题  ,网页ppt怎么弄成自己的ppt?  如何有效防御Web建站篡改攻击?  Laravel如何配置和使用队列处理异步任务_Laravel队列驱动与任务分发实例  黑客入侵网站服务器的常见手法有哪些?  Laravel如何处理JSON字段的查询和更新_Laravel JSON列操作与查询技巧  新三国志曹操传主线渭水交兵攻略  Laravel如何自定义错误页面(404, 500)?(代码示例)  *服务器网站为何频现安全漏洞?  如何快速查询域名建站关键信息?  Windows11怎样设置电源计划_Windows11电源计划调整攻略【指南】  如何用狗爹虚拟主机快速搭建网站?  手机网站制作与建设方案,手机网站如何建设?  如何用wdcp快速搭建高效网站?  Laravel怎么进行数据库回滚_Laravel Migration数据库版本控制与回滚操作  在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?  深圳防火门网站制作公司,深圳中天明防火门怎么编码?  长沙企业网站制作哪家好,长沙水业集团官方网站?  Laravel如何实现API速率限制?(Rate Limiting教程)  html5的keygen标签为什么废弃_替代方案说明【解答】  微博html5版本怎么弄发超话_超话进入入口及发帖格式要求【教程】  Java垃圾回收器的方法和原理总结  如何快速搭建高效简练网站?  谷歌浏览器如何更改浏览器主题 Google Chrome主题设置教程  手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?  Laravel PHP版本要求一览_Laravel各版本环境要求对照  Laravel怎么实现验证码功能_Laravel集成验证码库防止机器人注册