zoukankan      html  css  js  c++  java
  • 跨域调用webapi

    web端跨域调用webapi

     
    在做Web开发中,常常会遇到跨域的问题,到目前为止,已经有非常多的跨域解决方案。
    通过自己的研究以及在网上看了一些大神的博客,写了一个Demo
    首先新建一个webapi的程序,如下图所示:
    由于微软已经给我们搭建好了webapi的环境,所以我们不必去添加引用一些dll,直接开始写代码吧。
     
    因为这只是做一个简单的Demo,并没有连接数据库。
    第一步我们要在Models文件夹里添加一个实体类Employees,用来存放数据。
    Employees.cs里的内容如下:
    复制代码
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Web;
     5  
     6 namespace APIApplication.Models
     7 {
     8     public class Employees
     9     {
    10         public int? Id { get; set; }
    11         public int? DepartmentId { get; set; }
    12         public string Name { get; set; }
    13         public string Job { get; set; }
    14         public string Gender { get; set; }
    15         public string PhoneNum { get; set; }
    16         public string EmailAdderss { get; set; }
    17         public string Address { get; set; }
    18     }
    19 }
    复制代码
    添加完实体类之后我们的重头戏即将开始,那就是controller
    接着我们在Controller文件夹下新建一个控制器,取名叫EmployeesController
    注意在添加控制器的时候要选择空API控制器模板
    如图所示:
    在控制器里我们要添加如下代码:
    在添加代码之前我们要添加引用:using APIApplication.Models;
    复制代码
    1 static List< Employees> emps;
    2         static EmployeesController()
    3         {
    4             emps = new List< Employees>();
    5             emps.Add( new Employees { Id = 1, DepartmentId = 1, Name = "张三", Gender = "男" , Job = "ASP.NET工程师" , PhoneNum = "1886                       0922483", EmailAdderss = "zhangsan@123.com" , Address = "江苏省苏州市独墅湖大道228号" });
    6             emps.Add( new Employees { Id = 2, DepartmentId = 2, Name = "李四", Gender = "女" , Job = "web前端工程师" , PhoneNum = "1886                       0922483", EmailAdderss = "lisi@123.com" , Address = "江苏省苏州市独墅湖大道228号" });
    7         }
    复制代码
    这段代码的作用就是往实体Employees类里存储数据。这里我只添加了两条数据仅供大家参考。
     
    接下来我们要实现CRUD功能:
    复制代码
     1 public IEnumerable <Employees > Get(int ? id = null )
     2         {
     3             return from employee in emps where employee.Id.Equals(id) || string.IsNullOrEmpty(Convert .ToString(id)) select employee;
     4         }
     5         public void Post( Employees employee)
     6         {
     7             employee.Id = 3;
     8             emps.Add(employee);
     9         }
    10         public void Put( Employees employee)
    11         {
    12             emps.Remove(emps.Where(e => e.Id == employee.Id).First());
    13             emps.Add(employee);
    14         }
    15         public void Delete( int id)
    16         {
    17             emps.Remove(emps.Where(e => e.Id == id).FirstOrDefault());
    18         }
    复制代码
    在这里Get是获取员工传入参数id是返回的就是对应id的数据,为空就是全部数据
    Post是添加数据
    Put是修改数据Put比较特殊,它在执行修改的时候是根据修改数据的ID去查找这条数据,然后删除掉,在添加新的数据。
    Delete当然就是删除了。
     
    接下来是见证奇迹的时刻。我们点击运行,在浏览器里输入localhost:****/api/employees
    然后我们会看到一个XML的文档
    如下图所示:
    到此我们完成了几个基本的WebApi的Get方法。
    今天我们讲的是跨域调用WebApi
    什么是跨域呢?
    JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象。通常来说,跨域分为以下几类:
    在跨域问题上,域仅仅是通过“URL的首部”来识别而不会去尝试判断相同的ip地址对应着两个域或两个域是否在同一个ip上。
    想详细了解跨域的同学可以访问:http://twlidong.github.io/blog/2013/12/22/kua-yuan-zi-yuan-gong-xiang-cross-origin-resource-sharing-cors/
     
    了解了跨域之后我们要开始继续往下看了。
    web端调用api分为前端调用即(AJAX)后端调用即(.net)
    我先从AJAX开始讲如何实现跨域
    首先新建MVC项目,这里我就不截图了,相信大家都会的。
    这里我们用Jquery的ajax()方法,mvc默认会帮我们引入jquery
    我们只需要写如下代码就可以了:
    复制代码
     1 <script>
     2     $(document).ready( function () {
     3         $.ajax({
     4             type: 'GET',
     5             url: 'http://localhost:7974/api/employees/get',
     6             dataType: 'JSON',
     7             success: function (data) {
     8                 alert( "姓名:" + data[0].Name + " 性别:" + data[0].Gender + " 住址:" + data[0].Address);
     9             }
    10         });
    11     })
    复制代码
    这里的url是你的api的地址映射/api/employee/get是调用get方法获取所有数据
    为了方便演示我就把获取的数据alert出来了。
    按照我的步骤你们一定没有成功吧?
    大家思考一下为什么会出现如下错误信息
    在这里跟大家解释一下 Access-Control-Allow-Origin是HTML5中定义的一种服务器端返回Response header,用来解决资源(比如字体)的跨域权限问题。
    当Access-Control-Allow-Origin后面跟URL 或 *,如果是 URL 则只会允许来自该 URL 的请求,* 则允许任何域的请求
    例如:header('Access-Control-Allow-Origin:http://A.abc.com')||header('Access-Control-Allow-Origin:*')
    意思是说只有当你请求的资源被允许跨域的时候才可以被访问。
    那么我们该怎么设置Access-Control-Allow-Origin呢?
    带着这个问题我么能继续我们的教程
    为了解决跨域问题我们要自定义一个CrossSite的属性
    在项目根目录新建一个类
    内容如下:
    复制代码
     1 using System.Web;
     2 using System.Web.Http.Filters;
     3 using System.Web.Mvc;
     4 
     5 namespace APIApplication
     6 {
     7     public class CrossSiteAttribute : System.Web.Http.Filters.ActionFilterAttribute
     8     {
     9         private const string Origin = "Origin";
    10         /// <summary>
    11         /// Access-Control-Allow-Origin是HTML5中定义的一种服务器端返回Response header,用来解决资源(比如字体)的跨域权限问题。
    12         /// </summary>
    13         private const string AccessControlAllowOrigin = "Access-Control-Allow-Origin" ;
    14         /// <summary>
    15         ///  originHeaderdefault的值可以使 URL 或 *,如果是 URL 则只会允许来自该 URL 的请求,* 则允许任何域的请求
    16         /// </summary>
    17         private const string originHeaderdefault = "http://192.168.13.7:8002" ;
    18         /// <summary>
    19         /// 该方法允许api支持跨域调用
    20         /// </summary>
    21         /// <param name="actionExecutedContext"> 初始化 System.Web.Http.Filters.HttpActionExecutedContext 类的新实例。</param>
    22         public override void OnActionExecuted( HttpActionExecutedContext actionExecutedContext)
    23         {
    24             actionExecutedContext.Response.Headers.Add(AccessControlAllowOrigin, originHeaderdefault);
    25         }
    26     }
    27 }
    复制代码
    然后我们可以在EmployeesController中添加[CrossSite]属性
    用法是这样的:
    复制代码
    1 [CrossSite]
    2  public IEnumerable<Employees > Get(int ? id = null )
    3  {
    4    return from employee in emps where employee.Id.Equals(id) || string.IsNullOrEmpty(Convert .ToString(id)) select employee;
    5  }
    复制代码
    然后重新生成解决方案,运行后可以看到刚才的警告框的数据了。
     
    前端的调用已经结束了,下面让我们看看后端是如何调用的吧。
    在MVC项目里的Models里我们需要一个实体模型用来读取或设置数据
    新建类命名为v_employees
    复制代码
     1 public class v_employees
     2     {
     3         public int? id { get; set; }
     4         public int? departmentid { get; set; }
     5         public string name { get; set; }
     6         public string job { get; set; }
     7         public string gender { get; set; }
     8         public string phonenum { get; set; }
     9         public string emailadderss { get; set; }
    10         public string address { get; set; }
    11     }
    复制代码
    后端我采用的是HttpClient
    具体用法如下:
    复制代码
     1         private HttpClient client = new HttpClient ();
     2         private string url = "http://192.168.13.7:8001/api/employees/get" ;
     3 
     4         public async Task< ActionResult> Index()
     5         {
     6             ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
     7 
     8             var data = await client.GetAsync(url);
     9             var employees = data.Content.ReadAsAsync<IEnumerable <v_employees >>();
    10             List< v_employees> emps = employees.Result.ToList();           
    11             ViewData[ "employees"] = emps;
    12             return View();
    13         }
    复制代码

    然后在Index页面设置ViewData

    在页面里就可以直接使用数据emps了

    复制代码
    1 @foreach ( var item in emps)
    2 {
    3     <ul >
    4         <li >@ item.name</ li>
    5         <li >@ item.gender</li >
    6         <li >@ item.address</li >
    7     </ul >
    8 }
    复制代码

    运行后的效果如下:

    未完待续。

    本教程会持续更新。

  • 相关阅读:
    Linux中磁盘mbr分区——实践篇
    Linux中磁盘分区——理论篇
    Linux中常用压缩打包工具
    自动化(脚本)安装httpd服务
    CentOS6.8环境下搭建yum网络仓库
    CentOS下rpm命令详解
    CentOS下yum命令详解
    CentOS7.3环境下源码安装httpd
    js对url进行编码和解码(三种方式区别)
    前端paging分页,前端设置每页多少条和当前页面的索引,传给后端,数据显示出来
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/4780650.html
Copyright © 2011-2022 走看看