Angularjs跨域调用Asp.Net WebAPI
之前写过一篇使用jQuery跨域调用WebAPI的博客《jQuery跨域调用Asp.Net Web API》,但最近使用Angularjs来调用WebAPI发现之前的方法行不通。本文主要介绍解决使用Angularjs调用WebAPI的跨域问题。
环境
- Angularjs1.4.7
- Asp.Net WebAPI2
- IIS:IIS8.0
- VS:VS2013
- .Net Framework:4.5
服务端跨域实现
这里的服务端指的是Asp.Net WebAPI,根据最近查过的些资料,大概有三种实现方式:
方式一: 使用《在jQuery跨域调用Asp.Net Web API》一文中介绍的方式;
方式二: 使用自定义的Attribute,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class CrossSiteAttribute : System.Web.Http.Filters.ActionFilterAttribute { private const string Origin = "Origin"; /// <summary> /// Access-Control-Allow-Origin是HTML5中定义的一种服务器端返回Response header,用来解决资源(比如字体)的跨域权限问题。 /// </summary> private const string AccessControlAllowOrigin = "Access-Control-Allow-Origin"; /// <summary> /// originHeaderdefault的值可以使 URL 或 *,如果是 URL 则只会允许来自该 URL 的请求,* 则允许任何域的请求 /// </summary> private const string originHeaderdefault = "*"; /// <summary> /// 该方法允许api支持跨域调用 /// </summary> /// <param name="actionExecutedContext"> 初始化 System.Web.Http.Filters.HttpActionExecutedContext 类的新实例。</param> public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { actionExecutedContext.Response.Headers.Add(AccessControlAllowOrigin, originHeaderdefault); } }
|
方式三: 另一种自定义的Attribute,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public class CorsPolicyProvider : Attribute, ICorsPolicyProvider { private CorsPolicy _policy; public CorsPolicyProvider() { // Create a CORS policy. _policy = new CorsPolicy { AllowAnyMethod = true, AllowAnyHeader = true, AllowAnyOrigin = true };
// Magic line right here _policy.Origins.Add("*");
}
public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, CancellationToken cancellationToken) { return Task.FromResult(_policy); } }
|
如果是普通的js或jQuery跨域调用,服务端进行上面的设置基本就可以了,但在Angularjs中,还是无法成功调用,通常会报下面的错误:
Angularjs中的设置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| var app = angular.module('app', []); app.config(['$httpProvider', function ($httpProvider) { // Use x-www-form-urlencoded Content-Type $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
// Override $http service's default transformRequest $httpProvider.defaults.transformRequest = [function (data) { /** * The workhorse; converts an object to x-www-form-urlencoded serialization. * @param {Object} obj * @return {String} */ var param = function (obj) { var query = ''; var name, value, fullSubName, subName, subValue, innerObj, i;
for (name in obj) { value = obj[name];
if (value instanceof Array) { for (i = 0; i < value.length; ++i) { subValue = value[i]; fullSubName = name + '[' + i + ']'; innerObj = {}; innerObj[fullSubName] = subValue; query += param(innerObj) + '&'; } } else if (value instanceof Object) { for (subName in value) { subValue = value[subName]; fullSubName = name + '[' + subName + ']'; innerObj = {}; innerObj[fullSubName] = subValue; query += param(innerObj) + '&'; } } else if (value !== undefined && value !== null) { query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&'; } }
return query.length ? query.substr(0, query.length - 1) : query; };
return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data; }]; }]);
|
参考
http://www.codeproject.com/Articles/742532/Using-Web-API-Individual-User-Account-plus-CORS-En
http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api