支持Ajax跨域访问ASP.NET Web Api 2(Cors)的示例教程

随着深入使用ASP.NET Web Api,我们可能会在项目中考虑将前端的业务分得更细。比如前端项目使用Angularjs的框架来做UI,而数据则由另一个Web Api 的网站项目来支撑。注意,这里是两个Web网站项目了,前端项目主要负责界面的呈现和一些前端的相应业务逻辑处理,而Web Api则负责提供数据。

这样问题就来了,如果前端通过ajax访问Web Api项目话,就涉及到跨域了。我们知道,如果直接访问,正常情况下Web Api是不允许这样做的,这涉及到安全问题。所以,今天我们这篇文章的主题就是讨论演示如何配置Web Api以让其支持跨域访问(Cors)。好了,下面我们以一个简单的示例直接进入本文的主题。

首先打开Visual Studio 2013,创建一个空白的解决方案,命名为:CrossDomainAccessWebAPI。

再创建一个空的Web Api项目,命名为:CrossDomainAccess.WebAPI

接着我们右键单击刚才创建的解决方案,创建一个空的Web项目用来模拟我们的网站对WebAPI项目进行跨域调用,如下:

完成以上步骤以后,我们的解决方案目录如下图所示:

下面我们在模拟网站的Web项目中通过Nuget添加jQuery,一下是添加jQuery包的界面:

添加完成后,到这里我们就完成了前期的准备工作。下面在WebAPI项目的Models文件夹中添加是一个实体类UserInfo,具体代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace CrossDomainAccess.WebAPI.Models
{
 public class UserInfo
 {
  public int Id { get; set; }

  public string UserName { get; set; }

  public string UserPass { get; set; }

  public string Email { get; set; }

  public DateTime RegTime { get; set; }
 }
}

然后在WebAPI项目中添加一个示例控制器:UserInfoController,这个控制器用来返回数据集合,具体代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using CrossDomainAccess.WebAPI.Models;

namespace CrossDomainAccess.WebAPI.Controllers
{
 public class UserInfoController : ApiController
 {
  /// <summary>
  /// 获取用户信息集合的方法
  /// </summary>
  /// <returns>返回用户信息集合</returns>
  public IHttpActionResult GetList()
  {
   //对象集合模拟数据
   List<UserInfo> list = new List<UserInfo>()
   {
    new UserInfo()
    {
     Id = 1,
     UserName = "张三",
     UserPass = "FDASDFAS",
     Email = "zhangsan@163.com",
     RegTime = DateTime.Now
    },
    new UserInfo()
    {
     Id = 2,
     UserName = "李四",
     UserPass = "FDASDFAS",
     Email = "lisi@163.com",
     RegTime = DateTime.Now
    },
    new UserInfo()
    {
     Id = 3,
     UserName = "王五",
     UserPass = "FDASDFAS",
     Email = "wangwu@163.com",
     RegTime = DateTime.Now
    },
    new UserInfo()
    {
     Id = 4,
     UserName = "赵六",
     UserPass = "FDASDFAS",
     Email = "zhaoliu@163.com",
     RegTime = DateTime.Now
    },
    new UserInfo()
    {
     Id = 5,
     UserName = "田七",
     UserPass = "FDASDFAS",
     Email = "tianqi@163.com",
     RegTime = DateTime.Now
    },
    new UserInfo()
    {
     Id = 6,
     UserName = "王八",
     UserPass = "FDASDFAS",
     Email = "wangba@163.com",
     RegTime = DateTime.Now
    }
   };
   return Ok(list);
  }
 }
}

接着我们需要修改一下App_Start目录下的WebApiConfig.cs文件中webapi的路由规则,以便通过api/{controller}/{action}的方式进行访问,同时让修改序列化方式,让WebAPI默认输出json格式的数据,具体操作如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Formatting;
using System.Web.Http;

namespace CrossDomainAccess.WebAPI
{
 public static class WebApiConfig
 {
  public static void Register(HttpConfiguration config)
  {
   // Web API 配置和服务

   // Web API 路由
   config.MapHttpAttributeRoutes();

   config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
   );
   //清除所有序列化格式
   config.Formatters.Clear();
   //添加Json格式的序列化器
   config.Formatters.Add(new JsonMediaTypeFormatter());
  }
 }
}

重新生成一下项目,并在浏览器中访问,这时我们可以的到json格式的数据,如下:

代码如下:

[{"Id":1,"UserName":"张三","UserPass":"FDASDFAS","Email":"zhangsan@163.com","RegTime":"2016-04-21T10:36:50.7800569+08:00"},{"Id":2,"UserName":"李四","UserPass":"FDASDFAS","Email":"lisi@163.com","RegTime":"2016-04-21T10:36:50.7800569+08:00"},{"Id":3,"UserName":"王五","UserPass":"FDASDFAS","Email":"wangwu@163.com","RegTime":"2016-04-21T10:36:50.7800569+08:00"},{"Id":4,"UserName":"赵六","UserPass":"FDASDFAS","Email":"zhaoliu@163.com","RegTime":"2016-04-21T10:36:50.7800569+08:00"},{"Id":5,"UserName":"田七","UserPass":"FDASDFAS","Email":"tianqi@163.com","RegTime":"2016-04-21T10:36:50.7800569+08:00"},{"Id":6,"UserName":"王八","UserPass":"FDASDFAS","Email":"wangba@163.com","RegTime":"2016-04-21T10:36:50.7800569+08:00"}]

好了,到这里我们Web Api端的数据输出就准备好了。为了测试是否可以跨域访问,我们再转到CorsDemo.UI网站项目中。首先创建一个index.aspx页面(这个命名自己可以任意取)后打开,修改成如下的代码:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="CrossDomainAccess.Web.Index" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <title></title>
 <script src="Scripts/jquery-2.2.3.min.js"></script>
 <script type="text/javascript">
  $(function () {
   $('#getData').click(function () {
    $.ajax({
     url: 'http://localhost:29867/api/UserInfo/getlist',
     dataType: 'json',
     success: function (data) {
      //以表格的形式在浏览器控制台显示数据,IE下不支持
      console.table(data);
     }
    });
   });
  });
 </script>
</head>
<body>
 <form id="form1" runat="server">
  <div>
   <input type="button" value="跨域获取数据" id="getData" />
  </div>
 </form>
</body>
</html>

完成以上步骤以后,启动WebAPI项目和Web项目,并在Web项目的Index页面中点击跨域获取数据按钮,打开浏览器控制台查看请求结果,在控制台会出现如下结果:

控制台提示我们跨域请求被阻止,同时提示CORS头部信息确实,所以我们可以通过去WebAPI配置CORS来让其支持跨域访问。

那现在我们在WebAPI项目中通过Nuget添加Microsoft.AspNet.WebApi.Cors ,然后在WebApiConfig.cs文件中配置HttpConfiguration的EnableCors方法即可。具体操作如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Formatting;
using System.Web.Http;
using System.Web.Http.Cors;

namespace CrossDomainAccess.WebAPI
{
 public static class WebApiConfig
 {
  public static void Register(HttpConfiguration config)
  {
   // Web API 配置和服务
   EnableCrossSiteRequests(config);
   // Web API 路由
   config.MapHttpAttributeRoutes();

   config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
   );
   //清除所有序列化格式
   config.Formatters.Clear();
   //添加Json格式的序列化器
   config.Formatters.Add(new JsonMediaTypeFormatter());
  }

  /// <summary>
  /// 允许跨域调用
  /// </summary>
  /// <param name="config"></param>
  private static void EnableCrossSiteRequests(HttpConfiguration config)
  {
   //对所有的请求来源没有任何限制
   var cors = new EnableCorsAttribute(
    origins: "*",
    headers: "*",
    methods: "*"
    );
   config.EnableCors(cors);
  }
 }
}

现在,我们再重新生成WebAPI项目并运行,接着在页面http://localhost:31521/Index.aspx中点击按钮“跨域获取数据”,通过firebug的控制台,我们可以看到数据跨域加载成功了,如下:

更多精彩内容,请点击《ajax跨域技术汇总》,进行深入学习和研究。

至此,关于ASP.Net Web Api支持跨域请求的示例和演示就完成了,谢谢大家的阅读。

(0)

相关推荐

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

    概述 ASP.NET Web API 的好用使用过的都知道,没有复杂的配置文件,一个简单的ApiController加上需要的Action就能工作.但是在使用API的时候总会遇到跨域请求的问题,特别各种APP万花齐放的今天,API的跨域请求是不能避免的. 在默认情况下,为了防止CSRF跨站的伪造攻击(或者是 javascript的同源策略(Same-Origin Policy)),一个网页从另外一个域获取数据时就会收到限制.有一些方法可以突破这个限制,那就是大家熟知的JSONP, 当然这只是众多

  • Javaweb使用cors完成跨域ajax数据交互

    跨域,指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制. ajax本身实际上是通过XMLHttpRequest对象来进行数据的交互,而浏览器出于安全考虑,不允许js代码进行跨域操作,所以会警告. cors 全称:Cross-Origin Resource Sharing 中文意思:跨域资源共享 它在维基百科上的定义是:跨域资源共享(CORS )是一种网络浏览器的技术规范,它为Web服务器定义了一种方式,允许网页从不同的域访问其资源.而

  • 支持Ajax跨域访问ASP.NET Web Api 2(Cors)的示例教程

    随着深入使用ASP.NET Web Api,我们可能会在项目中考虑将前端的业务分得更细.比如前端项目使用Angularjs的框架来做UI,而数据则由另一个Web Api 的网站项目来支撑.注意,这里是两个Web网站项目了,前端项目主要负责界面的呈现和一些前端的相应业务逻辑处理,而Web Api则负责提供数据. 这样问题就来了,如果前端通过ajax访问Web Api项目话,就涉及到跨域了.我们知道,如果直接访问,正常情况下Web Api是不允许这样做的,这涉及到安全问题.所以,今天我们这篇文章的主

  • Python的Django应用程序解决AJAX跨域访问问题的方法

    引子 使用Django在服务器端写了一个API,返回一个JSON数据.使用Ajax调用该API: <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="maximum-scale=1.0,minimum-scale=1.0,user-scalable=0,width=device-width

  • 浅析JSONP解决Ajax跨域访问问题的思路详解

    前几天,工作上有一新需求,需要前端web页面异步调用后台的Webservice方法返回信息.实现方法有多种,本例采用jQuery+Ajax,完成后,在本地调试了一切ok,但是部署到服务器上以后就出现问题了,后台服务调用没有响应,怎么回事?代码没怎么改动,唯一修改的地方就是jQuery的ajax方法中的url地址.难道是这里的问题,经过检查和调试,发现原来是同源策略在作怪,我们知道,JavaScript或jQuery是在Web前端开发中经常使用的动态脚本技术.在JavaScript中,有一个很重要

  • 关于C#中ajax跨域访问问题

    最近因项目需要,需要跨域请求访问数据.跨域访问是指什么? [跨域]:指的是浏览器不能执行其他网站的脚本.它是由浏览器的同源策略造成的,是浏览器对JavaScript施加的安全限制.所谓同域是指,域名,协议,端口均相同,不明白没关系,举个栗子:例如,我的电脑上有2个服务器 192.168.0.11和192.168.0.12.如果第一个服务器上的页面要访问第二个服务器上面的数据,就叫做跨域.或者http://www.baidu.com 要访问http://www.xxx.com也是不同域名也是跨域.

  • JSONP跨域GET请求解决Ajax跨域访问问题

    前几天,工作上有一新需求,需要前端web页面异步调用后台的Webservice方法返回信息.实现方法有多种,本例采用jQuery+Ajax,完成后,在本地调试了一切ok,但是部署到服务器上以后就出现问题了,后台服务调用没有响应,怎么回事?代码没怎么改动,唯一修改的地方就是jQuery的ajax方法中的url地址.难道是这里的问题,经过检查和调试,发现原来是同源策略在作怪,我们知道,JavaScript或jQuery是在Web前端开发中经常使用的动态脚本技术.在JavaScript中,有一个很重要

  • ajax跨域访问报错501的解决方法

    问题:ajax跨域访问报错501 运行下面的代码会报错501 $.ajax({ type: "POST", url: "http://192.168.1.202/sensordata.php", contentType:'application/json; charset=utf-8', data: JSON.stringify(ajaxPostData), dataType:'json', success: function(data){ //On ajax su

  • Ajax跨域访问Cookie丢失问题的解决方法

    ajax跨域访问,可以使用jsonp方法或设置Access-Control-Allow-Origin实现,关于设置Access-Control-Allow-Origin实现跨域访问可以参考之前我写的文章<ajax 设置Access-Control-Allow-Origin实现跨域访问> 1.ajax跨域访问,cookie丢失 首先创建两个测试域名 a.fdipzone.com 作为客户端域名 b.fdipzone.com 作为服务端域名 测试代码 setcookie.PHP 用于设置服务端co

  • Ajax跨域问题及解决方案(jsonp,cors)

    跨域 跨域有三个条件,满足任何一个条件就是跨域 1:服务器端口不一致  2:协议不一致  3:域名不一致 解决方案: 1.jsonp 在远程服务器上设法动态的把数据装进js格式的文本代码段中,供客户端调用和进一步处理:在前台通过动态添加script标签及src属性,表面看上去与ajax极为相似,但是,这和ajax并没有任何关系:为了便于使用及交流,逐渐形成了一中非正式传输协议,人们把它称作 jsonp . 代码如下: html: <body> <form action="/&q

  • ajax跨域访问遇到的问题及解决方案

    Ajax请求一个目标地址为非本域(协议.域名.端口任意一个不同)的web资源,并根据响应获得外部应用数据.比如我们用Ajax访问城市天气预报.IP地址等公共服务接口时,就涉及跨域了.我们请求一个外部服务时,浏览器会基于安全问题拒绝授权访问. 而script.script.iframe标签的src属性就不存在跨域的问题,所以Ajax跨域就是利用这一点以及js对JSON的支持,外部服务只要给Ajax的请求响应一段JS代码或JSON数据,就能被Ajax获取到. 由于安全方面的原因, 客户端js使用xm

  • 详解Django解决ajax跨域访问问题

    这篇文章主要给大家介绍了关于Django跨域请求问题解决的相关资料,文中介绍的实现方法包括:使用django-cors-headers全局控制.使用JsonP,只能用于Get方法以及在views.py里设置响应头,只能控制单个接口,需要的朋友可以参考下. 使用Django在服务器端写了一个API,返回一个JSON数据.使用Ajax调用该API: 但是,Chrome浏览器提示错误: No 'Access-Control-Allow-Origin' header is present on the

随机推荐