• Web API 跨域请求


           分布式技术在项目中会频繁用到,以前接触过WebService(可跨平台)、WCF(功能强大,配置繁琐),    最近由于上层业务调整,将原来的MVC项目一分为三,将数据层提取出来,用API去访问。然后新建一类库项目,集成大量的辅助类来帮助MVC web端去访问Web API。

           VS2013上新建WebAPI的时候会多一个区域Areas的文件夹,这个区域可以看成是一个mini的MVC项目,我向来本着技术不够,篇幅来凑的原则,来初步记录下API的基础学习,API和MVC还是有区别的,对于新手,比如我,狭隘的自认MVC主用户请求返回视图界面,API主用户请求返回数据。访问API一般分为 Jquery中的Ajax 访问、HttpClient访问,今天在这里,先写一写Ajax与Web API的那些事。

    一、建Web API 项目

         1、建立Web API项目之后,在Model文件夹下建立实体数据模型

         2、新建一控制器StudentController,写个根据学生ID返回学生对象的方法

        public class StudentController : ApiController
        {
            IBCCEntities db = new IBCCEntities();
            //返回学生信息集合
            public IEnumerable<Student> AllStu() 
            {
                return db.Student;
            }
            
            //根据学生ID查询学生信息
            //根据路由规则 调用: api/Student/id
            public Student GetStuById(int id) 
            {
                Student student = db.Student.FirstOrDefault(m => m.StudentID == id);
                return student;
            }
    
        }

       3. 在该项目上新建一视图,用来请求后台API数据(同项目协议、端口、域名都相同,不存在跨域问题)

     <script type="text/javascript">
            $(document).ready(function () {
                $("#btnID").click(function () {
                    var id = $("#txtID").val();
                    $.getJSON("/api/Student/" + id, function (data) {
                        var html = "<ul>";
                        $(data).each(function (i, data) {
                            html += "学号:" + data.StudentID + "<br/>"+"姓名:" + data.StudentName + "<br/>"+
    "班级:"+ data.StudentClass +"<br/>"+"成绩:"+data.grade+"<br/>"+"入学时间:"+data.updatetime+"<br/"; }); $("#contactID").html(html); }); }); }); </script>

    只是一个最简单的Ajax调用后台,因为前台需要接收数据,所以后台Student控制器返回的学生数据对象,而不是视图

         

    二、客户端异步调用Web API

           当客户端不在服务器上, 客户端调用API是存在跨域问题的,异步调用的跨域(协议、端口号、域名)问题该怎么处理,上文演示的前台发起请求,后台API返回数据,下面来模拟客户端来调用API,另新建一MVC项目作为客户端,起始和上面前台界面相同,为了作比较,写一个ajax的底层用法

    <script type="text/ecmascript">
        $(function () {
            $("#btnID").click(function () {
                var id = $("#txtID").val();
                $.ajax({
                    type: "GET",
                    dataType: "json",
                    url: "http://localhost:11308/api/Product/"+id,
                    success: function (data) {
                        var html = "<ul>";
                            $(data).each(function (i, item) {
                                html += "学号:" + data.StudentID + "<br/>" + "姓名:" + data.StudentName + "<br/>" +
                            "班级:" + data.StudentClass + "<br/>" + "成绩:" + data.grade + "<br/>" + "入学时间:" + data.updatetime + "<br/";
                            });
                            html += "</ul>";
                            $("#contbyId").html(html);
                    },
                    error: function () {
                        alert("發送失敗");
                    }
                });
            })
        });
    </script>

    而此时进行请求,发现浏览器会提示 加载失败,请求不被允许。

    由于启动每个项目时,配置的端口号不同,所以调用API项目时,就产生的跨域,不是任何客户端都能得到服务端回执数据的,如果不在后台给客户端MVC项目的访问权限,客户端是接收不到服务端返回的数据,

    处理方法:

    1.在客户端添加一个类文件,用作过滤器,将客户端的URL地址写进去

        public class ProductFilter:System.Web.Http.Filters.ActionFilterAttribute
        {
            private const string Origin = "Origin";
            private const string AccessControlAllowOrigin = "Access-Control-Allow-Origin";
            private const string originHeaderdefault = "http://localhost:20630";
            public override void OnActionExecuted( HttpActionExecutedContext actionExecutedContext)
            {
              actionExecutedContext.Response.Headers.Add(AccessControlAllowOrigin, originHeaderdefault);
            }
        }

    2.添加特性,把这种行为标注到一个过多个控制器或动作方法上。如:把该类文件名放置StudentController方法上

            //根据学生ID查询学生信息
            //根据路由规则 调用: api/Student/id
            [StudentFiltet]
            public Student GetStuById(int id) 
            {
                Student student = db.Student.FirstOrDefault(m => m.StudentID == id);
                return student;
            }

    目前这样虽然能达到效果,如果有多个客户端来调用此服务端的API,那岂不是需要把所有客户端的URL加到服务端,如果用一个“泛称” 添加服务端的过滤器中,这样就类似于公开接口,

    如下:

            private const string Origin = "Origin";
            private const string AccessControlAllowOrigin = "Access-Control-Allow-Origin";
            //private const string originHeaderdefault = "http://localhost:20630";
            public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
            {
                actionExecutedContext.Response.Headers.Add(AccessControlAllowOrigin, "*");
            }

    用了泛称 *  代替具体的客户端好值之后,该API的接口便等于 公开接口,写的这里前台Ajax 调用API 基本如此,后面会介绍HttpClient调用API。

     世人皆大笑,举手揶揄之    

  • 相关阅读:
    jquery做的图片挂起的效果
    Android数据存储之DOM解析XML文件(输出部分)
    Android数据存储之JSON数据解析(输出部分)
    Android网络编程之Web Service获取天气预报( 获取省市填充下拉列表)
    Android数据存储之DOM解析XML文件(读取部分)
    Android网络编程之一个Android登录系统模块的实现(服务器端)
    Android数据存储之XmlPull解析XML文件(读取部分)
    Android数据存储之XmlPull解析XML文件(输出部分)
    Android数据存储之JSON数据解析(读取部分)
    Android网络编程之一个Android登录系统模块的实现(客户端)
  • 原文地址:https://www.cnblogs.com/Sientuo/p/6439455.html
Copyright © 2020-2023  润新知