目前的项目是前端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. p2p 打洞技术

    根据通信双方所处网络环境不同,点对点通信可以划分成以下三类:i> 公网:公网ii>公网:内网iii>内网:内网前两种容易实现,我们这里主要讨论第三种.这其中会涉及到NAT和NAPT的 ...

  2. View 动画 Animation 运行原理解析

    这次想来梳理一下 View 动画也就是补间动画(ScaleAnimation, AlphaAnimation, TranslationAnimation...)这些动画运行的流程解析.内容并不会去分析 ...

  3. 大话命令之--ss

    大话命令之-ss ss是Socket Statistics的缩写.顾名思义,ss命令可以用来获取socket统计信息,它可以显示和netstat类似的内容. 优势: (1)显示更多更详细的有关TCP和 ...

  4. console.log的返回值undefined

    console.log(fun());  function fun(){ console.log(1); } //////输出结果为: 1 undefined console.log(fun());  ...

  5. 如何转换MySQL表的引擎

    有很多种方法可以将表的存储引擎转换成另一种引擎.每种方法都有其优缺点,在这里介绍四种方法: 选择优先级(pt-online-schema-change > 创建与查询 > 导出和导入 &g ...

  6. 【JavaScript for循环实例】

    1.大马驮2石粮食,中马驮1石粮食,两头小马驮一石粮食,要用100匹马,驮100石粮食,该如何调配? //驮100石粮食,大马需要50匹 for(var a=0;a<=50;a++){ //驮1 ...

  7. C++STL vector简单使用练习1

    #include <iostream> #include <vector> #include <numeric> using namespace std; int ...

  8. [hdu5225][BC#40]Tom and permutation

    好久没写题解了..GDKOI被数位DP教做人了一发,现在终于来填数位DP的大坑了>_<. 发现自己以前写的关于数位DP的东西...因为没结合图形+语文水平拙计现在已经完全看不懂了嗯. 看来 ...

  9. LightOJ1012-Guilty Prince-DFS

    Guilty Prince  Time Limit: 2 second(s) Memory Limit: 32 MB Once there was a king named Akbar. He had ...

  10. 2017ecjtu-summer training # 11 POJ 2492

    A Bug's Life Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 38280   Accepted: 12452 D ...