外部调用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)再次运行项目,用外部调用

posted @ 2017-12-22 15:16  小小邪  阅读(2246)  评论(0编辑  收藏  举报