WebApi 研习之路:跨域问题(上)后台处理跨域问题

已经开始学习WebApi有一段时间了,但是可能使用的情况一直停留在一个比较窄的思路里,属于那种有坡度的开发和学习路径。想必大家已经看到过学习陡险这类似的图形,我现在差不多就是这种情况了,感觉自己学习了,会用了。案例习题都懒得去动,已有问题来了,想去弄才发觉自己学的东西都是零呀。悲催了,我的哥。

好了废话不说,今天我们来看一下跨域的问题。

1.什么是跨域问题

至于跨域问题的说法网络是比较多的,我这边只简单说明一下。具体链接我可以提供一个其他博友写的文章,还是不错的,我这里只针对该问题做一个总结和理解吧。

跨域问题:案例:比如http://www.baidu.com (百度)和http://www.sogou.com(搜狗) 两个域名。有一天搜狗说我这边想请求要给百度图片资源里的高清大图,因为搜狗这边没有,又不想自己做一个图片,想坐享其成。然后利用网络请求一个图片。像<img src='http://www.baidu.com/img/big.png'/>,当我们在浏览器的调试工具中,F12打开,在NetWork部分进行跟踪。会出现问题,因为Html5的规范,组织浏览器请求其他域的资源(或许说法不准确,就是这个意思),比如我的域名下有cookie,其他网站请求我的,我能给他吗?当然不行,我的资源我独享。当然这种也没有什么的,只是读取嘛,要是你想改变我的资源呢?比如Post 或Put,做一些不安全的操作,那不是乱套了。这就是跨域的问题来了。比如我真的要请求资源怎么办?比如,公司的服务器分布有多个:video.a.com  file.a.com .看看域名就知道是一个公司,他想两边想互相去资源,结果不行了。那怎么办?凉拌呗。。。。

2.跨域处理的办法

好了,上面瞎说了比较多了,现在开始说说处理的办法吧。起始也是有的。首先可以从服务端着手处理,其次客户端也做处理。服务端这就是我们说的跨域处理Cors.客户端:主要在js上比如Jsonp、Iframe、等 。这是什么意思呢?简单一点就是,我从服务端如何处理跨域,我从客户端如何处理跨域。本次先将服务端的跨域问题,在下一节中我在说明一下客户端的解决办法。

3.webapi 如何处理跨域难题。(本章的重点)

重点来了,因为我这边只说明解决办法,没有整个项目的源码,所有说,我会先说明下方法,要靠各位先理解然后尝试。所谓吃的苦中苦方为人上人嘛,多折腾才会成长。

从我看到的文章来看主要是利用Cors来解决的,也就是说服务端需要加入一个Access-Control-Allow-Origin Response 头。来告诉服务器,我可以跨域请求哦。

1) 引用微软的WebApi.Cors 动态库文件,如何添加呢?右键项目名,点击“管理Nuget 程序包”-->“浏览”-->“搜索” 名称“输入关键字就可以了”WebApi.Cors“,选择第一个安装。

2)下面是准备两个web项目:1.客户端-->请求方(web),2.服务端-->应答方(webapi)

3) 修改代码:下面是三种处理办法,归结来说还是一种,只是程序处理地方不同而已。

添加引用:system.web.cors;system.web.http.cors;

3.1 在api 的webapiconfig.cs 添加程序:

        public static void Register(HttpConfiguration config)
        {
            // Web API 配置和服务
            // 跨域配置
            //1. 只需要在这里添加该项即可
            //config.EnableCors(new EnableCorsAttribute("*","*","*"));

            //2. 添加配置项
            // 2.1在webconfig中添加配置项
            // 2.2 在register中添加cors配置
            #region register 配置
            var allowedMethods = ConfigurationManager.AppSettings["cors:allowedMethods"].ToString();
            var allowedOrigin = ConfigurationManager.AppSettings["cors:allowedOrigin"].ToString();
            var allowedHeaders = ConfigurationManager.AppSettings["cors:allowedHeaders"].ToString();
            var geduCors = new EnableCorsAttribute(allowedOrigin,allowedMethods, allowedHeaders)
            {
                SupportsCredentials = true
            };
            config.EnableCors(geduCors);
            #endregion 
            //3. 利用特性配置在某一个controller 或action上面。
            // Web API 路由
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }

代码中注释的部分:

config.EnableCors(new EnableCorsAttribute("*","*","*"));

  直接启动程序即可。

当然前提条件式,你的ui端有对这个webai 中某一个接口有ajax请求。

var ApiUrl = "http://localhost:8001/"; //服务端端口
$(function () {
    $.ajax({
        type: "get",
        url: ApiUrl + "api/Charging/GetAllChargingData",
        data: {},
        success: function (data, status) {
            if (status == "success") {
                $("#div_test").html(data);
            }
        },
        error: function (e) {
            $("#div_test").html("Error");
        },
        complete: function () {

        }
    });
});

启动项目时,要将项目设置成多项目程序启动,因为有了api服务后,你才可以请求呀,不然你到哪里去请求数据。就是说webapi 启动了,并且web去请求。

结果呢,成功了,对所有的域名。

3.2 这个其实是对第一个的改版而已。请请求需要的配置内容放到了webconfig中了。

这次利用途中为注释的部分2.

并在webconfig中添加对应配置项目。

    <add key="cors:allowedMethods" value="*"/>
    <add key="cors:allowedOrigin" value="http://localhost:27239"/>
    <add key="cors:allowedHeaders" value="*"/>

 代码中”http://localhost:27239"是说谁可以请求我的资源。

从代码中EnableCorsAttribute(string origin,string methods,string headers) ,一看就能明白,第一个参数表示:允许谁可以请求我(origin);第二个参数:请求的头文件:比如我们添加的头信息

第三个参数:请求的方式(getpostputdelete)四种比较常见的方式;

设置完毕后,运行程序,你会发现只有当请求web origin 是http://localhost:27239 才会成功返回数据,哪怕是多了一个’/‘都不可以的。

3.3 这种事简单的方式了。出去之前的所有配置,利用特性的方法:直接在Controller上面或者Action上面添加特性即可。

 [EnableCors(origins: "http://localhost:27239", headers:"*",methods:"GET,POST,PUT,DELETE")]
    public class ChargingController : ApiController
    {
        [HttpGet]
        public string GetAllChargingData()
        {
            return "Success";
        }

或者将attribute 添加到action 上面。

好了,好了从上面的三个方法中你看到了什么,发现其中都是调用的EnableCorsAttribute 特性,只不过是调用的时机不同而已了。

今天就先说到这里,有些地方会匆忙没能说明白的,我后期会慢慢补充。

同时很感觉博友的支持。附上作者链接如下:特别说明下,我只做知识的总结。

1. 跨域的解决办法

2. 跨域的详解

原文地址:https://www.cnblogs.com/zhaosw/p/7487838.html