外部调用mvc的api方法时,如何解决跨域请求问题?
首先,创建一个mvc项目(包含webapi),我们模拟一个场景
1)在项目的Controller 创建一个WeiXinApiController
public class WeiXinApiController : ApiController { WeiXinApiService service = new WeiXinApiService(); [System.Web.Http.HttpGet] public string GetCultureLevel() { //获取文化程度的方法 AppResult result = service.GetCultureLevel(); //返回json格式 return JsonConvert.SerializeObject(result,Newtonsoft.Json.Formatting.Indented); } }
2) 在项目的Model中创建一个WeixinApiService的业务类
public class WeiXinApiService { public dynamic GetCultureLevel() { //定义一个key/value的集合 Dictionary<int, string> dicts = new Dictionary<int, string>(); dicts[1] = "初中"; dicts[2] = "高中"; dicts[3] = "中专"; dicts[4] = "大专"; dicts[5] = "本科"; dicts[6] = "硕士"; dicts[7] = "博士"; //声明返回的数据类 AppResult result = new AppResult(); try { dynamic list = dicts; if (list.Count > 0) { result.Success = true; result.Message = "返回成功"; result.Data = list; } else { result.Success = false; result.Message = "返回失败"; } } catch (Exception ex) { result.Success = false; result.Message = ex.Message; } return result; } }
3)在项目新建一个文件夹Common,创建一个AppResult类(返回数据类)
public class AppResult { public AppResult() { } public AppResult(bool bo, string msg) { _Success = bo; Message = msg; } private bool _Success = false; /// <summary> /// 调用是否成功 /// </summary> public bool Success { get { return _Success; } set { _Success = value; } } /// <summary> /// 返回的信息 /// </summary> public string Message { get; set; } /// <summary> /// 返回数据 /// </summary> public object Data { get; set; } }
4)运行起来,用浏览器访问对应api控制器方法,是可以调用返回数据的
注:http://localhost:29303/api/Weixinapi/GetCultureLevel 路径是我本地项目路径
5)用外部调用这个api方法时,就会出现跨域访问问题(调用时,保持项目是运行的)
我们用DW测试,引用一个jquery.min.js文件,调用jquery的ajax请求方法进行请求
html页面
<body> <input type="button" value="调用测试" onClick="Test()"/> </body>
js 方法
<script type="text/javascript" src="jquery.min.js"></script> <script type="text/javascript"> var Test = function(){ $.ajax({ type: 'GET', url: 'http://localhost:29303/api/Weixinapi/GetCultureLevel', asyuc: true, jsonp: 'jsoncallback', success: function (datalist) { //将数据转化为json格式 var dt = JSON.parse(datalist); //判断是否返回成功 if (dt.Success) { console.log(dt); } else{ console.log(dt.Message); } } }); } </script>
出现跨域问题
那么如何解决跨域请求的问题呢?我在网上找到解决方法(添加支持跨域请求的属性)
6)在项目添加文件夹Attributes,新建一个CrossSiteAttribute.cs类
/// <summary> /// 控制Api接口是否支持跨域调用 /// </summary> 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 = "*";//"http://192.168.13.7:8002"; /// <summary> /// 该方法允许api支持跨域调用 /// </summary> /// <param name="actionExecutedContext"> 初始化 System.Web.Http.Filters.HttpActionExecutedContext 类的新实例。</param> public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { actionExecutedContext.Response.Headers.Add(AccessControlAllowOrigin, originHeaderdefault); } }
7)在原先api控制器的方法前加上这个属性
public class WeiXinApiController : ApiController { WeiXinApiService service = new WeiXinApiService(); [System.Web.Http.HttpGet] [CrossSiteAttribute] public string GetCultureLevel() { //获取文化程度的方法 AppResult result = service.GetCultureLevel(); //返回json格式 return JsonConvert.SerializeObject(result,Newtonsoft.Json.Formatting.Indented); } }
8)再次运行项目,用外部调用
平时多记记,到用时才能看看,记录你的进步,分享你的成果