目前的项目是前端mv*+api的方式进行开发的,以前都是没有跨域的方案,前后端人员在同一个解决方案里边进行开发,前端人员要用IIS或VS来开发和调试Api,这样就很不方便,迫切需要跨域访问Api.

评选了很多解决方案最终选择,CORS+WebApi

cors科普:http://www.ruanyifeng.com/blog/2016/04/cors.html

cors网站:http://enable-cors.org/

mvc源码:https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Http.Cors/CorsMessageHandler.cs

快速入门可以看一些教程,自己要扩展源码是一条捷径.

示例代码:https://github.com/gutun/aspnet/tree/master/cors

1.新建WebApi项目实现CORS跨域

1.1 新建一个新的项目CrossDomain

1.2. 安装 Microsoft.AspNet.WebApi.Cors

Install-Package Microsoft.AspNet.WebApi.Cors

1.3. 配置App_Start目录下的 WebApiConfig文件

Config中要启用 CORS的支持我选择默认的MediaType为json方式。

1.4 新增UserController,在里边新增两个方法,get用来ping,代表url是通的,post模拟真正的数据提交,我们所有的api访问走post, request的入参和出参可以定义通用的实体。这里模拟post提交数据解析成UserInfo的实例。

2.JQuery Ajax跨域

<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<script>
$.ajax({
url:'http://localhost:64542/api/user',
type:'POST',
data:{"Id":"1","Name":"张三"},
dataType:'json',
//Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
//contentType: 'application/json; charset=utf-8',
cache: false,
crossDomain: true,
success:function(data){
alert(data);
}
});
</script>
</body>
</html>

使用Nodejs本地服务器访问WebApi项目,成功的访问到了api/User,状态是200.

3.IE8,IE9支持CORS.

CORS在浏览器的支持情况,IE8和IE9是部分兼容,86%的浏览器是支持的,占了大部分,为了支持IE8和IE9我找到了一个补丁jquery.transport.xdr.min.js 用来弥补在IE8和IE9下的不足。

https://github.com/gfdev/javascript-jquery-transport-xdr.js

<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script>
<script src="http://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script>
<!--[if (IE 8)|(IE 9)]>
<script src="http://cdn.rawgit.com/gfdev/javascript-jquery-transport-xdr/master/dist/jquery.transport.xdr.min.js"></script>
<![endif]-->
</head>
<body>
<script>
//http://www.ruanyifeng.com/blog/2016/04/cors.html
$.ajax({
url:'http://localhost:64542/api/user',
type:'POST',
data:{"Id":"1","Name":"张三"},
dataType:'json',
//Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
//contentType: 'application/json; charset=utf-8',
cache: false,
crossDomain: true,
success:function(data){
alert(data);
}
});
</script>
</body>
</html>

喜出往外,跑起来后遇到了,415错误,未识别的Content-Type,这是因为在IE8和IE9下,Content-Type为空造成的。

http://stackoverflow.com/questions/18964258/asp-web-api-post-request-with-cors-and-ie9-xdomainrequest-objec

新增DefaultContentTypeMessageHandler用来处理Request

using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Cors;
using System.Web.Http.Cors; namespace CrossDomain
{
public class DefaultContentTypeMessageHandler : DelegatingHandler
{
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
CorsRequestContext corsRequestContext = request.GetCorsRequestContext();
if (corsRequestContext != null) //判断是否是跨域的请求
{
if (request.Method == HttpMethod.Post && request.Content.Headers.ContentType == null) //ConentType为空,使用默认值
request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded");
} var response = await base.SendAsync(request, cancellationToken); return response;
} }
}

再次更改WebApiConfig文件,在MessageHandlers管道中追加刚写的DefaultContentTypeMessageHandler,这样ContentType为空的跨域请求会使用默认的ContentType.

using System.Web.Http;
using System.Web.Http.Cors; namespace CrossDomain
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//新增CORS支持
var corsAttr = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(corsAttr);
//默认使用json格式,移除xml格式
config.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
//处理Content-Type
config.MessageHandlers.Add(new DefaultContentTypeMessageHandler()); // Web API configuration and services // Web API routes
config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}

在chrome,IE8,IE9,IE10+上测试没有问题。

前后端分离之CORS和WebApi的更多相关文章

  1. 【开源】分享一个前后端分离方案-前端angularjs+requirejs+dhtmlx 后端asp.net webapi

    一.前言 半年前左右折腾了一个前后端分离的架子,这几天才想起来翻出来分享给大家.关于前后端分离这个话题大家也谈了很久了,希望我这个实践能对大家有点点帮助,演示和源码都贴在后面. 二.技术架构 这两年a ...

  2. WebAPI 实现前后端分离

    随着Web技术的发展,现在各种框架,前端的,后端的,数不胜数.全栈工程师的压力越来越大. 现在的前端的框架,既可以做各种Web,又可以做各种APP,前端框架更新换代越来越快,越来越多. 传统的模式 前 ...

  3. WebAPI 实现前后端分离的示例

    转自:http://www.aspku.com/kaifa/net/298780.html 随着Web技术的发展,现在各种框架,前端的,后端的,数不胜数.全栈工程师的压力越来越大. 现在的前端的框架, ...

  4. ASP.NET WebApi+Vue前后端分离之允许启用跨域请求

    前言: 这段时间接手了一个新需求,将一个ASP.NET MVC项目改成前后端分离项目.前端使用Vue,后端则是使用ASP.NET WebApi.在搭建完成前后端框架后,进行接口测试时发现了一个前后端分 ...

  5. 无需CORS,用nginx解决跨域问题,轻松实现低代码开发的前后端分离

    近年来,前后端分离已经成为中大型软件项目开发的最佳实践. 在技术层面,前后端分离指在同一个Web系统中,前端服务器和后端服务器采用不同的技术栈,利用标准的WebAPI完成协同工作.这种前后端分离的&q ...

  6. 前后端分离java、jwt项目进行CORS跨域、解决非简单请求跨域问题、兼容性问题

    情况描述: 最近在部署一个前后端分离的项目出现了跨域问题*, 项目使用jwt进行鉴权,需要前端请求发起携带TOKEN的请求*,请求所带的token无法成功发送给后端, 使用跨域后出现了兼容性问题:Ch ...

  7. 前后端分离 导致的 静态页面 加载 <script type="module" > 报CORS 跨域错误,提示 blocked by CORS policy

    1.前言 静态页面 加载 <script type="module" > 报CORS 跨域错误,提示Access to script at ftp:///xxx.js ...

  8. dotnetcore vue+elementUI 前后端分离架二(后端篇)

    前言 最近几年前后端分离架构大行其道,而且各种框架也是层出不穷.本文通过dotnetcore +vue 来介绍 前后端分离架构实战. 涉及的技术栈 服务端技术 mysql 本项目使用mysql 作为持 ...

  9. [开源] angularjs + Asp.net 前后端分离解决方案

    本文版权归 博客园 萧秦 所有,此处为技术收藏,如有再转,请于篇头明显位置标明原创作者及出处,以示尊重! 作者:萧秦 原文:http://www.cnblogs.com/xqin/p/4862849. ...

随机推荐

  1. vscode运行前端代码

    vscode 可安装静态web服务器  Live Server用于运行前端代码,方便调试.最新的 Live Server已支持php动态页面. 安装方法是,点击左侧第五个图标,打开"扩展&q ...

  2. Android-AnsyncTask异步任务

    同步和异步的概念区别: 同步,必须执行完成某个问题后才能继续执行其他的. 异步,我会去先执行其他问题,你执行完之后返回给我一个结果就可以. android中为什么要引用异步任务呢 android启动的 ...

  3. (译)JToken的层次结构

     原文地址:https://stackoverflow.com/questions/38558844/jcontainer-jobject-jtoken-and-linq-confusion/3856 ...

  4. 深入理解ES6之—数据解构

    一 对象解构 对象解构语法在赋值语句的左侧使用了对象字面量 let node = { type: true, name: false } //既声明又赋值 let { type, name } = n ...

  5. React Native学习(二)—— 开始一个项目

    本文基于React Native 0.52 一.创建一个项目 1.初始化一个RN项目 react-native init RNDemo 2.连接一个设备或是打开模拟器 可以通过 adb devices ...

  6. html遮罩层设置

    .shade{ position: fixed; top: 0; bottom: 0; left: 0;right: 0; background-color: black; opacity: 0.6; ...

  7. 【margin和padding的区别】

    margin和padding的区别 margin是指从自身边框到另一个容器边框之间的距离,就是容器外距离.(外边距) padding是指自身边框到自身内部另一个容器边框之间的距离,就是容器内距离.(内 ...

  8. BZOJ 1001: [BeiJing2006]狼抓兔子【最大流/SPFA+最小割,多解】

    1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 23822  Solved: 6012[Submit][ ...

  9. BZOJ 1083: [SCOI2005]繁忙的都市【Kruscal最小生成树裸题】

    1083: [SCOI2005]繁忙的都市 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2925  Solved: 1927[Submit][Sta ...

  10. CodeForces-2015 HIAST Collegiate Programming Contest-Gym-100952A.水题 100952B.水题 100952C.回文字符串 100952D.杨辉三角处理组合数 其他题目待续。。。

    哈哈哈哈哈哈哈,最近一直在补题,改各种错误的代码,wa了20多遍,改到心态爆炸,改好之后,感觉世界都美好了(叉会腰~)... A. Who is the winner? time limit per ...