webapi 订阅
今天的web计算平台包含了广泛的功能,其中的大部分均可以通过API(应用程序编程接口)访问。从简单的社会书签服务del.icio.us,到复杂得多的amazon s3'全虚拟化存储平台,想想能用这些web api做点什么,真是惊人。在本文中,我把web平台归为6个基本设施,并简要概述些相关产品。其间的线索是这些产品都提供了API,这意味着他们本身可以被其他服务整合。 展开全文
今天的web计算平台包含了广泛的功能,其中的大部分均可以通过API(应用程序编程接口)访问。从简单的社会书签服务del.icio.us,到复杂得多的amazon s3'全虚拟化存储平台,想想能用这些web api做点什么,真是惊人。在本文中,我把web平台归为6个基本设施,并简要概述些相关产品。其间的线索是这些产品都提供了API,这意味着他们本身可以被其他服务整合。
信息
性    质
web计算平台
服务总类
存储服务,消息服务等
中文名
Web API
APi释义
应用程序编程接口
WeBAPI存储服务
存储服务关注抽象化和虚拟化存储。这个领域的领头羊是amazon s3,在article in web 2.0 journal中对其曾有较深入的探讨。对开发者而言,S3提供了极其精简抽象的如哈希表之类的API,允许你轻松存取信息。另一个有意思的服务是openemy,它提供了类似于文件系统接口的api,但增加了给文件标签的能力。今年早些时候,TechCrunch剖析了其他一些在线存储服务。但至今我们还没看到传说中颠覆性的存储服务,GDrive(来自google)和LiveDrive(来自微软),他们很大可能都会提供api。
收起全文
精华内容
参与话题
问答
  • Web Api简单使用方法

    千次阅读 2018-04-07 14:54:41
    1. 简单介绍什么是Web ApiREST属于一种设计风格,REST 中的 POST(新增数据),GET(取得数据),PUT(更新数据),DELETE(删除数据)来进行数据库的增删改查,而如果开发人员的应用程式符合REST原则,则它的服务为...

    1. 简单介绍什么是Web Api

    REST属于一种设计风格,REST 中的 POST(新增数据),GET(取得数据),PUT(更新数据),DELETE(删除数据)来进行数据库的增删改查,而如果开发人员的应用程式符合REST原则,则它的服务为“REST风格Web服务也称的RESRfulWeb API”

    微软的web api是在vs2012上的mvc4项目绑定发行的,它提出的web api是完全基于RESTful标准的,完全不同于之前的(同是SOAP协议的)wcf和webService,它是简单,代码可读性强的,上手快的,如果要拿它和web服务相比,我会说,它的接口更标准,更清晰,没有混乱的方法名称,有的只有几种标准的请求,如get,post,put,delete等,它们分别对应的几个操作,下面讲一下:

    GET:生到数据列表(默认),或者得到一条实体数据

    POST:添加服务端添加一条记录,记录实体为Form对象

    PUT:添加或修改服务端的一条记录,记录实体的Form对象,记录主键以GET方式进行传输

    DELETE:删除 服务端的一条记录

    2. 怎么理解的 Post Get Put 和Delete

    首先我们从MVC4WEBAPI模板自动创建的演示文件进行分析 


    从演示的列子,我们可以看到在Action 中没有使用[HttpGet]、[HttpPost] 等修饰,那究竟它是如何运作的呢

    Action 皆以HTTP 动词开头Get、Post、Put、Delete ,这个也是刚好符合 webapi的约定的,什么约定呢?

    你调用什么类型的方法 ,例如 post 方法,那么他就去 你的所有的 action 里面 去找 以 post 开头的方法 ,名字可以随便叫,例如 postToDataBase 等等,只要开头匹配 就可以了

    打个比喻,假设今天服务端收到了一个GET 请求时,会去查找对应的Controller 并且Action 以”Get…” 开头的方法,举个例子:GetMembers、GetTime,以此类推,如果我们从jQueryAjax 发出了一个POST 请求,也会自动对应到以”Post…”开头的Action 内,也就是说实际呼叫哪个Controller的Action 不是利用网址来决定,而是依照HTTP 所送出的请求来决定,这也就是非常典型的REST风格,而在Web API中也处理了回传的数据,让我们看看Get() 这个方法,回传IEnumerable的方法,等于我们拥有了强类型。

    我们再来看看默认的 api 路由表 


    这里,只注册到了controller,没有到action,因为api的action名称是有约定的。

    webapi大约有这样的约定:

    action名称中有get的,0参数,匹配路由到/控制器

    action名称中有get的,1参数,匹配路由到 /控制器/id

    action名称中有post的,0参数,匹配路由到post方式的/控制器

    action名称中有post的,1参数,匹配路由到post方式的/控制器/id

     对于返回,可以直接返回一个class,则apicontroller自动根据请求的content-type序列化成xml或者json。具体例子为,用ie打开相应api的url返回的是json,用chrome返回的就是xml。

     

    另外我们可以注意到在PostPut的方法参数有一个关键字[ FromBody ],而Get、Delete则没有。,事实上没有加[FromBody ]就默认为[FromUri ].

    [ FromBody ]表示由请求文件本体中取得资料,就像一般表单Post Submit一样,取得资料的来源是由请求本体中取得,而[ FromUri ]则表示由URI中取得资料,就像在网址列中的所夹带的参数

    在webapi的示范代码里,Get方法很简单只有一个id参数的传入并且是简单的int型,因此我们可以用http://localhost/api/Values/1 这样的请求执行Get(int id)方法,但事实上并非每个请求都只用一个简单的参数就可以能搞定,有时我们可能需要2个或以上的参数才能传递或者是获取到数据,我们可以到路由里面改为接受两个参数,分别为{ p1 } & { p2 }

    RouteTable.Routes.MapHttpRoute(

                name: "DefaultApi",

                routeTemplate: "webapi/{controller}/{p1}/{p2}",

                defaults: new { id =System.Web.Http.RouteParameter.Optional }

            );

    那么对应的Controller 里面获取Get的方法需要修改为

    publicstringGet(String p1, String p2)

            {

                return p1 + "/" + p2;

            }

    这种方法,虽然比较简单,但是如果我们的参数更多的时候,还是这样去修改路由也是很麻烦的,我们就采用下面的方法,直接传递类到后台

     

    3. 复杂传值,直接从前台传递一个类到后台接收

     我们先在前台页面,post方式,来传递一个类的2个值到后台

    我们在前台提交的页面设置方式为 post 提交 ,地址就指向我们的 webapi地址 

    定义一个简单的类

    由于我们是通过 Post方式提交的数据,那么后台接收的时候,就是用 FromBody 来进行接收,由于刚好我们传递的前台数据就是类的2个字段,那么后台接收的时候,也可以直接用类来接收,webapi会根据类型和字段来帮我们自动加载数据,获取到值.

    如果你这里是用 get 方式进行传值的,那么这里的 FromBody 就应该换成 FromUri 

    get方式来获取数据:

    我直接在前台,用一个超链接,里面指向我们的webapi 并且传递2个值,刚好是我们的UserInfo类的2个属性 

    即使我们传了一个不存在型别里的属性名称参数值,也不会引发错误,该参数只会被忽略掉

    例如,我们修改的例子,post提交的时候,我们新增加一个参数,这个参数在后台的 Userinfo类里面是没有对应的属性的,我们这样提交之后,后台接收到值,会自动忽略掉不在类属性里面的值

     

    最传统通过 request.form request.querystring 的方式的获取值

    我们传统的在aspx或者是一般处理程序里面获取值是通过request.querystringrequest.form来获取到.那么在 webapi里面,则是有些改变


     可以通过上面这种强转的方式获取,也可以直接

    var context =HttpContext.Current.Request;

    WEBAPI中的RequestHttpRequestMessage类型,不能像Web传统那样有querystringfrom 方法接收参数,而传统的HttpReqest的基类是HttpReqestBase.所以这里我们就直接使用(HttpContextBase)Request.Properties[“MS_HttpContext”]

     

    4. 前台调用,ajax来调用

    5. 后台调用,后台代码调用

    如果我们想不用Get/Post/Put/Delete ,怎么定义 ? 简单,我们自己在方法上打上接受动词标签 HttpPost HttpGet

    我们想通过get方法来调用其中一个方法 http://localhost:28160/api/xiaoxin/RequestToken

     

    这个时候就会直接报错请求的资源不支持 http 方法“GET” 

    再次调用其中的一个方法,并且传递参数过去

    http://localhost:28160/api/xiaoxin/AccessToken?name=joey&pwd=lee

    居然直接就报错了,提示 : 找到了与该请求匹配的多个操作 

    这里报错的坑爹原因是: 你以为你刚才那样写 url 是在调用AccessToken方法? 你太天真了,都说了, 我们的webapi是只绑定到 controller ,而不绑定到 action上的,调用什么方法,完全看你是用的 post 还是get方法,并且是根据action的名字里面有没有 post get 来匹配action ,我这里使用url的方式显然是get方法, 然后AccessToken?name=joey&pwd=lee 这么一大串,在路由里面实际就是代表了参数id, 当匹配到 controller 里面的时候,发现有2个 HttpGet 的方法, 但是 这2个方法,他们的参数名字都是一模一样的,所以就提示了, 找到了与该请求匹配的多个操作….那么如何修改呢? 

    展开全文
  • 前端之路(WebApi篇)

    千次阅读 多人点赞 2019-01-20 09:28:30
    什么是WebApi?  API(Application Programming Interface,应用程序编程接口), 通俗的讲,API就是编程语言给我提供的一些工具,通过这些工具,我们可以非常轻易的完成一些功能。 Web API : 是浏览器提供的 一套...

    什么是Api? 什么是WebApi? 

    API(Application Programming Interface,应用程序编程接口),

    通俗的讲,API就是编程语言给我提供的一些工具,通过这些工具,我们可以非常轻易的完成一些功能。

    Web API : 是浏览器提供的 一套操作网页(web)的方法(API), 通过这套API我们可以非常轻松的操作页面的元素浏览器的一些功能

    ECMAScript - JavaScript的核心

    • ECMAScript是一套标准, 规范了语言的基本语法和数据类型;

    • 与具体实现无关

    DOM - 文档对象模型

    • 一套操作页面元素的API

    • 通过DOM提供的API可以获取/操作网页上的元素。

    BOM - 浏览器对象模型

    • 一套操作浏览器功能的API

    • 通过BOM可以操作浏览器窗口, 比如刷新、控制浏览器跳转等;

     

    DOM - 文档对象模型

    DOM基本概念 (记)

    DOM ( Document Object Model ) 文档对象模型, 是W3C组织推荐的一套操作网页元素的API。

    DOM又称为文档树模型, 因为整个HTML文档是一个树形的结构

    代码:

    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <div></div>
        <p></p>
        <span></span>
    </body>
    </html>

    DOM中常见的概念 : (记忆)

    • 文档 document : 一个网页可以称为文档 ; (换句话说: 操作页面,其实就是操作document)

       console.log(document);
      // DOM 会把整个网页当成一个对象,我们操作这个网页, 只要操作这个document对象即可
      // DOM 会把网页中的所有的东西都当作对象
    • 节点node : 网页中的所有内容都是节点 (标签、属性、文本)

        <ul class="box">
          <!-- 这是一些测试 -->
          <li>测试</li>
          <li>测试</li>
          <li>测试</li>
        </ul>
        //  ul : 标签节点
        //  class="box" : 属性节点
        //   <!-- 这是一些测试 --> : 注释节点
        //  测试 : 文本节点
    • 元素 element : 网页中的标签节点

    • ul : 元素
      li : 元素

    DOM初体验

    <!-- 需求:有一个img标签,,我们来修改img的title属性 和 src 属性 -->

    在DOM中,想要操作一个元素,首先需要先获取到这个元素才能进行操作。

    document.getElementById() : 通过id 获取元素

    document.getElementById()
    //功能:通过id 获取元素
    document : 文档对象
    get : 得到  
    element:元素 
    by:通过 
    id:id值
    // 参数 : 字符串类型的id
    //返回值 : 一个元素 一个对象
    var div = document.getElementById('div');
    console.dir(div);
    

    关于console.logconsole.dir的区别

    • console.log打印一个元素的时候,是以标签的形式进行展示的

    • console.dir打印一个元素的时候,是以对象的形式进行展示的

    在DOM中,页面标签的属性和DOM对象的属性是一一对应的,因此我们可以通过修改DOM对象的属性来修改标签的属性。

    // img对象 和 img标签 一一对应的 
    // 以后想要操作img标签,,只需要操作 img对象即可 
    var img =  document.getElementById('img');
    // console.dir(img.id);
    // console.dir(img.src);
    // console.dir(img.title);

     

    使用getElementById的注意事项

    • 如果id不存在,返回值为null

    • 在DOM中, document.getElementById('box') 方法需要写在html内容的后面, 保证页面加载完成之后才能获取到内容 (div标签就是)

    • Id 错写成 ID, 记得这是一个驼峰命名 : document.getElementById

    错误1 : 如果获取的是null,然后获取其属性
    Uncaught TypeError: Cannot read property 'title' of null
    错误2 : 方法写错Id=> ID错了   `getElementByID`
    Uncaught TypeError: document.getElementByID is not a function

    演示:

    <!--没有id-->
     <div id="box">前端学科</div>
    ​
    <script>
      //如果找不到,返回的是null,试图给null设置属性会报错
      var element = document.getElementById("box");
      element.title = "嘿嘿";//报错Uncaught TypeError: Cannot set property 'title' of null
    </script>
    

    事件的基本使用

    事件:理解为浏览器的感知系统 , 触发 --> 响应机制,javascript是基于事件驱动的。

    <!-- 需求 : 点击按钮切换图片 大 -->

    // 注册一个点击事件
    // btn : 你要点击谁
    // on 在...时候
    // click 点击
    //  结构 : 事件源.onclick = function() {..}
    

    事件三要素 : 事件源 + 事件名称 + 事件处理函数

    • 事件源 : 给谁注册事件 ( 按钮 btn )

    • 事件名称 : 注册了什么事件 ( click事件 )

    • 事件处理函数 : 事件触发后要执行的代码(函数形式)

    注意:事件处理函数并不会立马执行,而是当事件触发的时候才会执行(浏览器会自动调用)

    注册事件的基本语法 :

    var box = document.getElementById('box');
    //on:当  click:点击   当按钮被点击的时候触发
    box.onclick = function() {
      console.log('代码会在box被点击后执行');  
    };
    

    两种按钮

        <button>点亮</button>
        <input type="button" value="哈">
    ​
    都是可点击的普通按钮
    一个是文字显示在标签内容里, 而且还可以放其他标签
    一个是文字显示在vaue中

     

    修改标签的属性

    • 1.标签属性 : 标签的alt,title,src,width,height等属性,可以直接通过对象进行修改。

    • 2.样式属性 : 如果设置是样式 , 就要借助class属性,在js中class是关键字,因此对应的是className属性

    • 3.通过 innerText 属性和修改标签的内容

    var box = document.getElementById('box');
    box.innerText = '嘎嘎';
    

    getElementsByTagName

    <!-- 需求 : 点击按钮一次性修改多个 p 标签的文本内容 -->

    作用 : 通过标签名获取元素

    //参数:标签名
    //返回值:一个伪数组, 伪数组不是数组,不能使用属性的方法,但是可以跟数组一样进行遍历和使用下标进行操作。
    var ps = document.getElementsByTagName('p');
    
    注意:返回值有没有获取到元素,都是一个伪数组,即便元素只有一个
    

    找对象方法总结复习 (重要)

    1. 根据id获取元素

      // 第一个方法: getElementById()
      // 作用 : 根据 id值  , 获取元素
      // 参数 : 字符串 id值
      // 返回值 :  一个对象
      // 注意点 : element 
      // 方法 : 1个
      // document.getElementById();
      
    2. 根据标签获取元素

      // 第二个方法: getElementsByTagName()
      // 作用 : 根据 标签名 , 获取元素
      // 参数 : 字符串 标签名 
      // 返回值 : 数组 (一般使用的话 都是遍历) 
      // 注意点 : elements 
      // 方法 :  2个
      // document.getElementsByTagName() 
      // element.getElementsByTagName()
      • 方法 ( 2个 ) :

        //方法1 : 
        document.getElementsByTagName('div') //获取页面中所有的div标签
        // 方法2 :
        element.getElementsByTagName('li')       //获取 某个元素 中的所有li标签
      • 注意

        • 返回值是一个伪数组 伪数组不能直接使用数组的方法,,不过可以遍历或者通过下标来获取 (够用的了)

        • 伪数组不能直接注册事件,需要遍历后拿到标签再注册事件

        • 即使获取的标签只有一个,那也是数组,,只不过数组长度为1

     

    标签属性操作

    1.普通标签属性

    通过DOM设置普通标签属性,两边都会变化。常见的属性有:src、title、href、class、id等

    2.表单属性操作

    常见的表单属性有:disabled、type、value、checked、selected

    对于disabled、checked、selected三个属性来说,比较特殊。

    disabled : 禁用
    - true : 禁用
    - false : 不禁用
    checked : 多选框和单选框选中
    - true : 选中
    - false : 不选中
    selected : 菜单下拉框选中
    - true : 选中
    - false : 不选中
    在DOM对象中,他们的赋值.只要有值,很多都可以起到效果,但是为了统一规范, 我们使用 true/false
    

    3.标签的自定义属性

    我们之前讨论的属性,都是HTML规范中,标签本来就有的属性,对于标签自定义的一些属性比较特殊。

    在html页面中,定义一个自定义属性

    <div id="box" aa="bb"></div>
    // 给div标签中 添加不存在的未知属性aa, 这就是自定义属性

    attribute方法

    attribute系列方法用于设置 标签的属性 

    //设置标签的属性
    box.setAttribute(name, value);
    //获取标签的属性
    box.getAttribute(name);
    //移除标签的属性
    box.removeAttribute(name);

    总结 :

     // 1. 直接给标签里添加固有的属性 title 等 标签+对象里都有显示
     // 2. 给标签添加自定义属性  => 标签上 ok  +  对象里 不ok
     // 3. 给对象添加自定义属性  => 标签里 不ok  + 对象里 ok                     【掌握】
     //    自定义:  box.aa = bb;  只能给对象里添加,, 标签内是没有的
     //    获取话 : box.aa
     // 3. 自定义 : setAttribute 设置, 添加给标签内了获取的话 getAttribute       【掌握】
    

     

    标签的内容属性 innerText 和 innerHTML

    共同点 : 都是用来获取和设置标签的内容的

    区别 : innerHTML可以用于获取和设置标签的所有内容,包括标签和文本内容

    //innerHTML:内部的HTML
    //  获取标签内容的时候,不管标签还是文本,都能获取到
    //  innerHTML设置内容的时候,覆盖原来内容,标签也能生效,浏览器能解析这个标签。

    innerText可以用于获取和设置标签的文本内容,会丢弃掉标签

    //innerText:内部 文本
    //  获取标签内容的时候,只会获取文本,标签扔掉了
    //  设置标签内容的时候,覆盖原来内容,对标签进行转义(目的:把标签直接当文本来用)

    二者的区别:

    • innerHTML能够识别标签,标签能够生效

    • innerText只识别文本,标签会被转义。

    浏览器兼容性:指网页在各种浏览器上的显示效果不一致。或者是一些属性和方法在低版本的浏览器中不支持。

    //1. innerText是IE提出来的属性,因此低版本的火狐浏览器不支持这个属性。
    //2. 火狐有一个textContent属性,效果跟innerText一样,但是IE678不支持这个属性

    书写innerText的兼容性代码

    function getInnerText(element){
      if(typeof element.innerText === "string"){
        return element.innerText;
      } else {
        return element.textContent;
      }
    }

    使用:

      //innerHTML和innerText用哪个?
      //innerHTML:能够识别html标签,
      //innerText:不识别标签,
    ​
      //设置标签的内容,推荐使用 innerText
    

    获取元素的方法总结 [重要]

    根据id获取 (掌握)

    // getElementById
    // 作用 : 根据id 获取元素
    // 参数:元素的id
    // 返回值:一个元素,如果id不存在,返回null
    document.getElementById("id");

    根据标签名获取 (掌握)

    // getElementsByTagName
    // 作用 : 根据标签名 获取元素
    // 参数:标签名
    // 返回值:伪数组,无论有几个元素,返回都是伪数组
    document.getElementsByTagName("tagName");
    box.getElementsByTagName("tagName");
    ​
    //getElementsByTagNameNS 命名空间
     var btns =  document.getElementsByTagNameNS('*','button');

    这两个方法是没有任何兼容性问题的。

    根据类名获取

    // getElementsByClassName
    // 作用 : 根据类名获取元素 
    // 参数:字符串类型的类名
    // 返回值:伪数组
    document.getElementsByClassName("class")

    注意:这个方法ie678不支持

    根据name获取

    // getElementsByName
    // 作用 : 通过name属性值 获取元素
    // 参数 : name值
    // 返回值 : 伪数组
    var ps = document.getElementsByName("aa");
    

    根据css选择器获取 (重点)

    // 回顾 :
    // 简单选择器 : div .box #box
    // 复杂选择器 : * div,p p.div  div p div>p
    ​
    // 作用 : 根据css选择器获取
    //参数:是一个css选择器,,   如果是类选择器,  .demo   如果是id选择器:  #aa
    //返回值:只会返回一个对象,如果有很多个,会返回第一个
    document.querySelector();
    ​
    //参数:是一个css选择器
    //返回值:会返回伪数组,不管有多少个,都会返回伪数组
    document.querySelectorAll();

     

    行内样式操作(style属性)

    标签不仅可以通过class属性操作样式 (嵌套样式),还可以通过style属性操作样式 (行内样式)。

    同样的DOM对象可以通过className操作样式 (嵌套样式),也可以通过style属性操作样 (行内样式)。

    css : 嵌套样式 => js : 类名 div.className = 'red';

    css : 行内样式 => js : style对象 div.style.color = 'red';

    1.样式属性初体验

    //1. style 属性是一个对象, 里面存储了所有行内样式的键值对
    //2. style属性只能获取和设置 ` 行内样式 ` , 在类样式中,嵌套样式通过style获取不到的
    //3. 如果样式的名字带来-, 比如background-color, 到了 style对象中,变成了驼峰命名法 => backgroundColor (因为-在js中不是一个合法的标识符)

    style设置的样式是行内样式,,因为优先级要高于className设置的样式 ; 所以会出现一个覆盖,以行内样式为准 (行内样式 > 嵌套样式)

    <button>按钮</button>
    <div style="color:red;background-color:blue;">小马哥</div>
    //可以获取样式
    console.log(div.style);
    console.log(div.style.color);
    ​
    // 也阔以通过这种方式设置
    // 当时 css初始化 的属性
    div.style.color ='red';
    div.style.background = 'blue';
    div.style.width = '200px';
    div.style.height = '200px';
    div.style.fontSize = '100px';
    

    2.关于body的样式操作

    1. document.body :body比较常用, 并且在页面中是唯一的, 因此可以使用document.body直接获取   
    // 可以通过qs获取,也可直接获取
    2. document.documentElement :  可以获取html元素
    3. document.head : 可以直接获取head元素
    4. document.title : 可以直接获取title的文本
    

    事件学习

    1. 焦点事件 : onfocus 和 onblur 下的样式操作

    • onfocus : 当前元素 获得焦点 时会触发onfocus事件.

    • onblur : 当前元素 失去焦点 时会触发onblur事件.

    2. 鼠标事件 onmouseover 和 onmouseout 下的样式操作

    on 当...时候 mouse : 鼠标 over:经过 out:离开

    • onmouseover : 当 鼠标在元素上方 会触发 onmouseover 事件.

    • onmouseout : 当 鼠标离开 会触发 onmouseout 事件.

     

    关于cssText (了解)

    使用cssText可以设置style的属性值

    可以省略

    <div style="width:100px;height:100px">哈哈哈</div>
    //优点:可以一次性设置多个值
    //缺点:会覆盖其他值 不利于阅读
    var div =  document.querySelector('div');
    div.style.cssText = 'background:red;color:yellow';

     

    节点(元素)操作 (超级重要)

    1.节点属性 (了解)

    节点分类:

    ​ 元素节点、文本节点、属性节点、注释节点

    节点常用的属性

    • childNodes : 获取所有的子节点

    • nodeType:  节点类型:元素节点 = 1 属性-2(过时) 注释-8 文本-3

      nodeType链接-MDN

    • nodeName: 节点名称

    • nodeValue: 节点值

      <ul >
        <!-- 下面是li -->
        <li>导航1</li>
        <li>导航2</li>
        <li>导航3</li>
        <li>导航4</li>
      </ul>
    ​
    // childNodes 子节点(们)
    console.log(ul.childNodes);
    console.log(ul.childNodes[1]);
    

    2.节点查找 (重点)

    孩子节点

    //childNodes:获取所有的孩子节点(包括了元素节点和其他很多类型的节点,基本不常用)
    ★ children --- 获取所有的子元素(用途很广泛),兼容性:IE678会把注释节点算上。 
    ​
    //firstChild //第一个子节点  (基本不常用)
    ★ firstElementChild  --- 第一个子元素 有兼容性问题(IE678) 
    ​
    //lastChild //最后一个节点  (基本不常用)
    ★ lastElementChild --- 最后一个子元素 有兼容性问题(IE678) 
    ​
    // 第几个元素
    children[n] 第n个元素 
    ​
        
    <ul >
        <!-- 下面是li -->
        <li>导航1</li>
        <li>导航2</li>
        <li>导航3</li>
        <li>导航4</li>
    </ul>
    

    兄弟节点

    //1. nextSibling:下一个兄弟节点  (基本不常用)
    ★ 2. nextElementSibling:下一个兄弟元素(IE678不兼容)
    ​
    //3. previousSibling//上一个兄弟节点  (基本不常用)
    ★ 4. previousElementSibling //上一个兄弟元素 有兼容性问题 可以封装一个兼容性方法 
    

    【附加:事件学习】

    • onkeydown : 当用户 按下键盘上按键 时会触发onkeydown事件.

    • onkeyup : 在当前元素上 释放键盘按键 时会触发onkeyup事件.

    父亲节点

    ★ 1. parentNode:父节点  //没有兼容性问题
    

    3.添加节点 (重点)

    appendChild 在子元素的最后添加一个新元素

    语法:parent.appendChild(newChild)

    父元素.appendChild(子元素);

    parent : 调用者,父节点来调用

    newChild : 需要添加的那个孩子。

    作用 :把newChild添加到parent的孩子的 最后面。 (就相当于生孩子一样,最后的孩子,都是最小的最靠后的)

    注意 :: 如果添加的是页面中本来就存在的元素,是一个剪切的效果,原来的就不在了。

    ​
      <div>
          <li class="l1">我是li-1</li>
          <li class="l2">我是li-2</li>
          <li class="l3">我是li-3</li>
        </div>
       <hr> 
         <p class="other">我不是亲生的</p>

     

    insertBefore : 放在某个元素之前

    语法:parent.insertBefore(newChild, refChild);

    parent:必须要父节点来调用

    newChild:需要添加的那个节点

    refChild:添加到哪一个节点的前面。

    //  1. 拼接到最后  (常用)
    div.appendChild(p);
    ​
    // 2. 添加到s1之前 s2 s3之前  (常用)
    div.insertBefore(p,s1);
    ​
    // 3. 添加到最后一个
    div.insertBefore(p,null);
    ​
    // 4. 拓展 :非要添加在s2之后??
    // insertAfter?? no
    // p2.next
    div.insertBefore(p,s2.nextElementSibling);
    ​
    //5. 添加到父元素最前  (常用)
    div.insertBefore(p,div.children[0]);
    

    4.克隆节点 (重点)

    语法:var newNode = 节点.cloneNode(deep)

    功能:在内存中克隆一份节点

    参数:false / true

    • false:默认值:是浅复制,只会复制标签,节点本身,不会复制节点的孩子。

    • true: 深度复制,会复制标签,还会复制标签的所有内容 常用

    1. 克隆出来的节点跟原来的节点没有关系了,修改了也不会相互影响。

    2. 如果克隆的节点带了id,我们需要给id重新设置一个值,不让id冲突

        var newNode = div.cloneNode(true);
        // false : 浅复制  只复制该元素
        // true : 深复制   不仅复制该元素 还复制其子元素
    ​
         console.log(newNode);
    

    5.创建节点(3种方式) (重点)

    document.write(基本不用)

    可以生成新的节点,但是不推荐使用。如果页面已经加载完成了,你还是用document.write写内容的话,会把之前的页面给覆盖掉

    原理:页面从上往下加载的时候,会开启一个文档流,当页面加载完,文档流就会关闭。

    document.write的本意就是在文档流上写入内容。如果页面没加载完成,文档流还是开着的,document.write直接在这个文档流上写东西

    如果页面加载完成了,还是用document.write写东西,会重新开启一个新的文档流,往新的文档流上写东西,旧的文档流就被新的文档流覆盖了。

    window.onload = function () {
      document.write('你妹')
    }

    innerHTML (偶尔用)

    innerHTML也可以创建节点

    innerHTML创建节点的时候有一个特点,如果原来有内容的话,使用innerHTML会把原先的内容给干掉。

    慎用:很容易出现效率问题。

       div.innerHTML = '<h1>哈哈</h1>'
    

    createElement (常用)

    语法:var element = document.createElement("tagName");

    作用:在内存里面创建了一个节点

    返回:一个元素

          var div = document.querySelector('div')
          var h1 = document.createElement('h1');
          console.log(h1);
          h1.style.background = 'red';
          h1.innerText = '哈';
    ​
          div.appendChild(h1);
    

    6.删除节点 (重点)

    语法:parent.removeChild(child);

    解析 : 父元素.removeChild(子元素);

    功能:有父盒子调用,删除里面的一个子元素。

    //1 使用1 :
    div.removeChild(p);
    ​
    //2 使用2 :
    p.parentNode.removeChild(p);

    ​ // 总结 : //1. 正常情况下可以使用 chilrdren //2. 如果涉及到删除等情况 querySelectorAll

    7.替换节点

    语法:parentNode.replaceChild(newChild, oldChild);

    • newChild用来替换 oldChild的新节点,如果newChild已经存在于DOM树中,则它会被从原始位置删除。

     

    BOM

    BOM(Browser Object Model):浏览器对象模型,提供了一套操作浏览器功能的工具。

    BOM包含的内容很多,但是很多东西都不太常用,在BOM中需要大家掌握的大知识点就一个,那就是定时器 。 offset系列 还有一些其他小知识点


    window

    1. window对象是一个全局对象,也可以说是JavaScript中的顶级对象

    2. 像document、alert()、console.log()这些都是window的属性,其实BOM中基本所有的属性和方法都是属性window的。

    3. 所有定义在全局作用域中的变量、函数都会变成window对象的属性和方法

    4. window对象下的属性和方法调用的时候可以省略window

    window.onload(掌握)

    window.onload事件会在窗体加载完成后执行,通常我们称之为入口函数。

    window.onload = function(){
        //里面的代码会在 `窗体加载`完成后执行。
        // `窗体加载` 完成包括文档树(DOM html)的加载、还有图片、文件的加载完成。
    }

    如果有图片加载,那么代码一定要写到window.onload里面,否则会出现图片没有加载完成,获取到的宽度和高度不对的情况。

    浏览器会对页面的加载做优化,在加载图片的时候,图片的引入会延迟。

    <img src="./01.png" alt="">
    ​
    window.onload = function () {
    ​
      var img = document.querySelector('img');
      console.log(img.width);
      console.log(img.height);
    ​
    }
    ​
    //1.img也不能写在script的后面
    //2.要写在window.onload的里面
    

    window.open与window.close(了解)

    window.open() 打开一个窗口

    //语法:window.open(url, [name], [features]);
    //参数1:需要载入的url地址
    //参数2:新窗口的名称或者targt属性
        //_blank:如果指定为_blank,表示在新的窗口打开
    //参数3:窗口的属性,指定窗口的大小
    //返回值:会返回刚刚创建的那个窗口,用于关闭
    //示例:
    var newWin = window.open("http://www.baidu.com","_blank", "width=300,height=300");
    ​
    //参数配置:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/open

    window.close 关闭窗口

    newWin.close();//newWin是刚刚创建的那个窗口
    window.close();//把当前窗口给关闭了
    

    延时器与定时器 (★★★)

    setTimeout 延时器

    可以在延迟一定时间后执行指定的代码

    设置延时器

    // 语法: setTimeOut(callback,time)
    // 参数1: 回调函数, 时间到了就会执行
    // 参数2: 延时的时间  毫秒为单位 1s = 1000毫秒
    // 返回 : 定时器的id,用于清除
    var timer = setTimeOut(function(){
        //1秒后将执行的代码。
    }, 1000);
    

    清除延时器

    //语法 : clearTimeOut(timeerId)
    //参数 : 定时器id
    // 示例 : 
    clearTimeOut(timer) ; // 清除上面定义的定时器
    

    setInterval 定时器

    setInterval 方法重复调用一个函数或执行一个代码段,在每次调用之间具有固定的时间间隔。 (每隔一段时间执行一段代码)

    定时器除非清除,否则会一直执行下去。

    设置定时器

    // 语法 :var timerId = setInterval(func,dealy);
    // 参数1 : 重复执行的函数
    // 参数2 : 每次间隔的毫秒数
    // 返回 : 定时器的id,  用于清除
    // 示例 : 
    var timer = setInterval(function(){
      //重复执行的代码
    },1000);
    

    清除定时器

    //语法 : clearInterval(intervalId);
    //参数 : 定时器id
    // 示例 : 
    clearInterval(timerId) // 清除上面的定时器
    

    location 对象

    location 对象也是window的一个属性;

    location 其实对应的就是浏览器中的地址栏

    常用属性和方法

    location.href : 控制地址栏的地址

    location.href='http://www.baidu.com'; // 让页面跳转到百度首页
    

    location.reload() ; 让页面重新加载

    location.reload() ; // 刷新

    location的其他值

    可自行调试

    http://www.xmg.com:8080/index.html?id=666&psd=123#xxx   
    ​
    - location.hash  //哈希值 其实就是锚点     ==> #xxx
    - location.host  //服务器 服务器名+端口号  => www.xmg.com:8080
    - location.hostname //服务器名            =>  www.xmg.com
    - location.pathname //路径名             => index.html
    - location.port //端口                   => 8080
    - location.protocol //协议               => http 
    - location.search //参数                 => ?id=666&psd=123
    

    其他对象

    history对象表示页面的历史

    // 随便打开一个网页 可以演示
    //后退:
    history.back();
    history.go(-1);
    //前进:
    history.forward();
    history.go(1);

    screen 对象

    console.log(screen.width);//屏幕的宽度 
    console.log(screen.height);//屏幕的高度
    console.log(screen.availWidth);//浏览器可占用的宽度
    console.log(screen.availHeight);//浏览器可占用的高度
    

    offset系列 (重要)

    offset系列用于用于获取元素自身的大小和位置,在webapi中有广泛应用offset系列主要有:offsetHeight、offsetWidth、offsetParent、offsetLeft、offsetTop

    offsetHeight与offsetWidth

    offsetHeight与offsetWidth

    1.  获取的是元素真实的高度和宽度
    2.  获取到的是数值类型,方便计算
    3.  offsetHeight与offsetWidth是只读属性,不能设置。

    style.height与style.width

    1.  只能获取行内样式
    2.  获取到的是字符串类型,需要转换

    结论

    1. 设置宽度高度使用style.width与style.height
    2. 获取宽度和高度offsetWidth与offsetHeight

    offsetParent

    parentNode和offsetParent

    1. parentNode始终是父元素
    2. offsetParent是离当前元素最近的定位元素(absolute、relative),如果没有,那就找body

    offsetLeft与offsetTop

    offsetLeft: 自身左侧到offsetParent左侧的距离:left + margin-leftoffsetTop:自身顶部到offsetParent顶部的距离 : top + margin-top

    offsetLeft与offsetTop

    1.  元素自身与offsetParent真实的距离
    2.  获取到的是数值类型,方便计算
    3.  只读属性,只能获取,不能设置

    style.left与style.top

    1.  只能获取行内样式
    2.  获取到的是字符串,需要转换
    3.  可以获取,也可以设置

    结论

    获取操作:用offset系列  ==> 数值类型
    设置操作:用style.xxx进行设置。 ==> 字符串类型

    动画函数封装

    了解一下思路, 以后都是用封装好的

    ​ div:hover {

    ​ transition: all 4s;

    ​ transform: translateX(400px);

    ​ }

    动画初体验 (单方向移动)

    var timeId = setInterval(function () {
      var step = 10;
      var current = div.offsetLeft;
      //只有当当前的位置小于目标的位置的时候,才能走
      if(current < 400) {
        current += step;
        div.style.left = current + "px";
      }else {
        clearInterval(timeId);
      }
    }, 15);

    动画函数 (双方向移动)

          //3. 回到原点
          btn1.onclick = function () {
    ​
            var timerId =  setInterval(function () {
    ​
                //1. 获取当前位置
                var current = div.offsetLeft;
                var step = -9;
                var target = 0;
    ​
                if (current > target) {
    ​
                    //2. 累加小碎步
                    current += step;
    ​
                    //3. 重新赋值
                    div.style.left = current + 'px';
                  
                }else {
                  clearInterval(timerId);
                }
    ​
            },15);
            
          }
    

    动画函数封装

    1. step : 决定的是方向

    2. 关系什么时候会走? 目标距离-现在距离的之间的鹅距离只要大于一个步数, 就可以累加跳

    3. 也不可以 400-200 >9 可以 但是 0-200 >-9 就不对 需要移动,,我们要看的距离

    4. 不够一步的直接等于即可

    5. 一个对象添加了两个定时器是不好的,连续点会乱, 给对象添加一个timerId值,,这样的话

      每个元素只能绑定一个,如果多点了把之前的取消掉即可

    //动画函数封装
    function animate(element, target) {
      if(element.timeId) {
        clearInterval(element.timeId);
      }
      element.timeId = setInterval(function () {
        var current = element.offsetLeft;
        var step = current < target ? 10 : -10;
        //当目标位置距离当前位置的距离超过一步的时候,继续走
        if (Math.abs(target - current) >= Math.abs(step)) {
          current += step;
          element.style.left = current + "px";
        } else {
          clearInterval(element.timeId);
        }
      }, 15);
    }

     

    事件对象

    事件对象的概述

    在触发某个事件的时候,都会产生一个事件对象Event,这个对象中包含所有与事件相关的一些信息,包括触发事件的元素,事件的类型以及其他与事件相关的信息。

    鼠标事件触发时,事件对象中会包含鼠标的位置信息。

    键盘事件触发时,事件对象中会包含按下的键相关的信息。

     

    获取事件对象

    现代浏览器获取 : (掌握)

    // 给一个形参即可
    btn.onclick = function(event){
        //event就是事件对象,里面包含了事件触发时的一些信息。
        console.log(event);
    }

    低版本浏览器 (ie678): (了解)

    btn.onclick = function(){
        //IE678通过window.event获取事件对象
        console.log(window.event);
    }

    兼容性 :

    btn.onclick = function(event){
        //只要用到了事件对象,就要记得处理浏览器兼容性
        event = event || window.event;
    }

     

    事件对象的常用属性

    事件对象中有很多很多的属性,但是很多属性并不常用。我们经常用到的是鼠标位置信息 和键盘码 相关的信息。

    (一)记录了鼠标位置信息的相关属性

    • clientX与clientY: 相对于浏览器可视区左上角的位置 (常用)光标相对于可视区左上角的水平位置和垂直位置。

    • pageX与pageY:相对于网页内容左上角的位置光标相对于网页(文档document)左上角的水平位置与垂直位置

    • screenX与screenY:相对于屏幕左上角的位置光标相对于屏幕左上角的水平位置与垂直位置。

    document.onclick = function (e) {
        //获取事件对象
    ​
        //clientX  clientY  :获取的是鼠标在可视区的位置
        //pageX    pageY    :获取的是鼠标在整个页面中的位置: 包括scrollTop
        //screenX scrennY   :获取在屏幕中的位置
        console.log(e.clientX, e.clientY);
        console.log(e.pageX, e.pageY);
        console.log(e.screenX, e.screenY);
    }
    

     

    (二)记录了键盘码的属性

    事件学习:
    onkeydown : 键盘按下
    onkeyup : 键盘抬起
    适用于document和input等等
    ​
    event.keyCode:键盘按下的那个键的键盘码
    

    注册事件的两种方式

    1.on + 事件名称

    onclick、onmouseover这种on+事件名称的方式注册事件几乎所有的浏览器都支持。

    注册事件:

    box.onclick = function(){
        //事件处理程序    
    }

    移除事件:

    box.onclick = null; 

    缺点:

    同一个元素同一类型的事件,只能注册一个,如果注册了多个,会出现覆盖问题。

    2.注册事件的新方式 : addEventListener

    现代浏览器支持的注册事件的新方式,这种方式注册的事件不会出现覆盖问题。

    addEventListener的语法

    //第一个参数:事件的类型:click mouseover
    //第二个参数:函数,监听者,每次点击,这个函数就执行。
    element.addEventListener(type, func);
    ​
     btn.addEventListener('click',function () {
          console.log(111); 
     })

    removeEventListen的语法

    //第一个参数:参数类型
    //第二个参数:要移除的那个函数
    element.removeEventListener(type, func);
    ​
    btn.removeEventListener('click',fn);
    // 注意 : 如果想让注册的事件能移除,不能用匿名函数。

    低版本浏览器兼容问题: (了解)

    IE678不支持addEventListener与removeEventListen两个方法,但是支持attachEvent与detachEvent

    attachEvent的用法:

    //type:事件类型   需要加上on   onclick  onmouseenter
    //func:需要执行的那个事件
    attachEvent(type, func)
    ​
    //代码:
    var btn = document.getElementById('btn');
    btn.attachEvent('onclick',function () {
        alert(1)
    });

    detachEvent的用法

    //type:事件类型   需要加上on   onclick  onmouseenter
    //func:需要执行的那个事件
    detachEvent(type, func)

    兼容性封装(了解)

    //添加事件
    function addEvent(element, type, fn){
        //能力检测
        if(element.addEventListener){
            element.addEventListener(type, fn, false);
        }else if(element.attachEvent){
            element.attachEvent("on"+type, fn);
        }else {
            //如果都不行,那就用on方式
            element["on"+type] = fn;
        }
    }
    ​
    ​
    //移除事件
    function removeEvent(element, type, fn) {
        if(element.removeEventListener){
            element.removeEventListener(type, fn, false);
        }else if(element.detachEvent){
            element.detachEvent("on"+type, fn);
        }else {
            element["on"+type] = null;
        }
    }

     

    事件流

    事件冒泡

    当一个元素的事件被触发时,同样的事件将会在该元素的所有祖先元素中依次被触发。这一过程被称为冒泡

    说白了就是:当我们触发了子元素的某个事件后,父元素对应的事件也会触发。

     

    拓展 : 阻止事件冒泡 (掌握)

    代码 : event.stopPropagation();

    //1. 因为是事件的冒泡,,因事件引起,也要因事件停止
    father/son/sun.onclick = function (event) {
     
        //stop :停止  propagation:传播
        event.stopPropagation();
    }
    ​
    // onclick : 默认就是 第三个参数为 false:
     father.addEventListener('click',function(){
                alert('father');
      },false);
    ​
    // a 跳转 
    // return false;
    

    事件捕获 (了解)

    事件冒泡 是 ie 提出来的

    ​ 路径 : 触发事件的目标元素(sun) > son > father > body > document

    事件捕获是火狐提出来的

    路径 : document > body > father > son > 触发事件的目标元素 (sun)


    解析 : 事件的处理将从DOM层次的根开始,而不是从触发事件的目标元素开始,事件被从目标元素的所有祖先元素依次往下传递

    //当addEventListener第三个参数为true时,表示事件捕获
    // 参数3 : 是否捕获
    arr[i].addEventListener("click", function () {
        console.log(this);
    },true);
    

    事件的三个阶段 (掌握)

    1. 事件的捕获阶段

    2. 事件的目标阶段(触发自己的事件)

    3. 事件的冒泡阶段

    事件有三个阶段 :

    • 捕获事件和冒泡事件都存在 的话 , 首先发生的是捕获阶段, 然后 是目标阶段,,最后才是冒泡阶段,

    • addEventListener 第三个参数为是否捕获 ,

    • 如果为true时, 表示该事件在捕获阶段发生,

    • 如果为false时 , 表示该事件在冒泡阶段发生

    • 某一个事件只会执行一次

    代码演示 :

    // addEventListener 第三参数 是否捕获,,true : 捕获,,false:冒泡
    document.addEventListener('click',function () {
        alert('document')
    },true);
    document.body.addEventListener('click',function () {
        alert('body')
    },false);
    father.addEventListener('click',function () {
        alert('father')
    },true);
    son.addEventListener('click',function () {
        alert('son')
    },false);
    sun.addEventListener('click',function () {
        alert('sun')
    },true);
    

    常见的事件

    1.常见的鼠标事件

    • onclick:单击事件

    • ondblclick:双击事件

    • onmouseover:鼠标经过事件

    • onmouseout:鼠标离开事件

    • onmousemove:鼠标移动事件

    • onfocus:获得焦点事件

    • onblur:失去焦点事件

    • onmousedown:鼠标按下事件

    • onmouseup:鼠标弹起事件

    son.onmousemove = function (e) {
        // 到浏览器可视区左侧的距离
        console.log(e.clientX);   
    }
    

    2.常见的键盘事件

    onkeydown:键盘按下时触发

    onkeypress : 键盘按下时触发

    onkeyup:键盘弹起时触发

     

    三大家族

    offset家族 (都掌握)

    offset系列用于用于获取元素自身的大小和位置 ,在网页特效中有广泛应用

    offset家族主要有:offsetHeight、offsetWidth、offsetParent、offsetLeft、offsetTop

    offsetHeight与offsetWidth

    1. 获取的是元素真实的高度和宽度

    2. 获取到的是数值类型,方便计算

    3. offsetHeight与offsetWidth是只读属性,不能设置。

    style.height与style.width

    1. 只能获取行内样式

    2. 获取到的是字符串类型,需要转换

    总结

    //0. 要求 :  都要掌握
    //1. 获取以后用 : offsetWidth 和 offsetheight   
                    (内容大小+border+padding)
    //2. 设置以后用 : style.width 和 style.height
    

    scroll家族 (掌握1个)

    scroll家族是用来获取盒子内容的大小和位置

    scroll 家族主要有 : scrollWidth、scrollHeight、scrollLeft、scrollTop

    scrollWidth与scrollHeight

    1. scrollWidth与scrollHeight是盒子内容的真实的宽度和高度。与和盒子大小无关,仅仅与盒子的内容有关系。 (padding + 内容)

    2. 如果内容不超过盒子,盒子高度就是 scrollHeight ,(宽度同理)

    3. 如果内容超过盒子, 内容高度 就是scrollHieght

    scrollTop 被浏览器卷去的高度

    1. scrollTop用于获取内容垂直滚动的像素数。如果没有滚动条,那么scrollTop值是0

    2. 给内容超过盒子, 盒子设置 overflow:scroll 就可出现滚动条

    scrollLeft

    1. scrollLeft用于获取内容水平滚动的像素数

    2. 演示可以使用内容只是纯字母的

    3. 浏览器切忌这种出现水平滚动条,用户体验极差,避免

    onscroll 事件

    对于有滚动条的盒子, 可以使用onscroll注册滚动事件,,每滚动一像素,就会触发该事件

    var div = doucment.getElementById(“div”);
    div.onscroll = function(){
    ​
        console.log(div.scrollLeft);
        console.log(div.scrollTop);
    }

    总结 :

    //1. 要求 : 掌握 scrollTop 和 onscroll 事件
    

    场景 : 获取页面被卷去的高度和宽度 

    通常来说,scroll家族用的最多的地方就是用来获取页面被卷去的高度,非常的常用

    • 对于老式的浏览器,需要获取html或者body的scrollTop

    • 对于现在浏览器,使用window.pageYOffset进行获取

    页面被卷去的高度和宽度的兼容性封装

    // 给整个页面注册滚动事件
    document.onscroll = function() {
      var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
     var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0
    }
    

    client家族

    client家族用于获取盒子可视区的大小

    client家族有clientWidth、clientHeight、clientLeft、clientTop

    clientWidth、clientHeight 可视区宽高

    三大家族对比

     

    clientTopclientLeft 完全没有用,他们就是borderTop与borderLeft

    onresize事件:onresize事件会在窗口被调整大小的时候发生。

    window.onresize = function(){
        //事件处理程序
    }
    

    场景 : client系列一般用来获取页面的可视区宽高

    // 因为求的是窗口大小所以用window
    window.onresize =  function () {
    ​
        var W = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
        console.log(W);
    ​
        var H = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
        console.log(H);
    }
    

    大总结

    offset家族 : 真实宽高和位置

    1. width : 内容 + border + padding;
    2. offsetWidth : 真实宽度
    3. offsetHeight :真实高度
    4. offsetLeft : 真实左侧距离
    5. offsetTop : 真实顶部距离
    ​
    使用 : 
    1. 获取 offset系列
    2. 设置 style系列

    scroll家族 : 内容大小

    1. scrollTop : 被页面卷去的高度
    2. div.onscroll : 给div注册滚动事件 (前提是有滚动条)
    3. window.onscroll : 给整个页面注册滚动事件
    4. 获取 被页面卷去的高度
    window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop 
    5. 重点掌握 : pageYOffset 
    

    client 家族 可视区域大小

    1.window.onresize   onresize事件会在窗口被调整大小的时候发生。
    2. 可视区域大小 : window.innerWidth
    

     

    展开全文
  •  创建 Web API 项目在这里我们使用VS2013, .NET 4.5.1创建一个Web API 2的项目选择项目WEB API模板, 在最下方的MVC主要是默认会自带微软的API Helper, 使用MVC发布在这里不实用安全 这样我们一个项目就初始化好了,...

    这篇做为这个系列的第一篇,做基本的介绍,有经验的人可以直接跳到第二部分创建 ProductController。

     

    创建 Web API 项目

    在这里我们使用VS2013, .NET 4.5.1创建一个Web API 2的项目

    image

    选择项目WEB API模板, 在最下方的MVC主要是默认会自带微软的API Helper, 使用MVC发布

    image

    在这里不实用安全

    image

     

    这样我们一个项目就初始化好了, 这都要归功于微软强大的VS

    image

     

    F5启动项目之后, 点击界面上API按钮可以看到默认创建的API

    image

     

    这时就可以用上面的地址通过一些测试工具来测试了. 这里推荐使用fiddler, 后面我们也将广泛使用这款工具来做调试.

     

    创建我们自己的API-Products API

    相关操作步骤如下

    添加ProductController

    image

    image

    image

    image

     

    在这里我们设计产品相关的API URL如下, 虽然这个不完全符合RESTFul标准,如有纠结的人直接忽略, 这里主要介绍如何把我们的URL定制成下面这个样子(也是我们项目中的样子):

    当然这里的API URL还有其他写法,这个有兴趣的后面章节可以再讨论。

    我们的 Product API简单的设计为下面格式:

    添加获取产品分页API: api/products/product/getList 
    添加获取单个产品API: api/products/product/get?productId=产品ID 
    添加产品新增API: api/products/product/add?productId=产品ID 
    添加产品更新API: api/products/product/update?productId=产品ID 
    添加产品删除API: api/products/product/delete?productId=产品ID

    在这里我们在刚才新添加的ProductController里中实现上面的API

    复制代码
    [RoutePrefix("api/products")]
        public class ProductController : ApiController
        {
            [HttpGet, Route("product/getList")]
            public Page<Product> GetProductList()
            {
                throw new NotImplementedException();
            }
    
            [HttpGet, Route("product/get")]
            public Product GetProduct(Guid productId)
            {
                throw new NotImplementedException();
            }
    
            [HttpPost, Route("product/add")]
            public Guid AddProduct(Product product)
            {
                throw new NotImplementedException();
            }
    
            [HttpPost, Route("product/update")]
            public void UpdateProduct(Guid productId, Product product)
            {
                throw new NotImplementedException();
            }
    
            [HttpDelete, Route("product/delete")]
            public void DeleteProduct(Guid productId)
            {
                throw new NotImplementedException();
            }
        }
    复制代码

    添加之后启动程序,看到的结果如下

    image



    到这里大家加上自己的后端业务逻辑,完成业务层面的操作就可以发布使用了。

    文章转载来自:http://www.cnblogs.com/Flyear/p/4870373.html

    展开全文
  • Web API 入门指南

    千次阅读 2018-06-28 19:08:50
    Web API是一个比较宽泛的概念。这里我们提到Web API特指ASP.NET Web API。这篇文章中我们主要介绍Web API的主要功能以及与其他同类型框架的对比,最后通过一些相对复杂的实例展示如何通过Web API构建http服务,同时...

    Web API是一个比较宽泛的概念。这里我们提到Web API特指ASP.NET Web API。

    这篇文章中我们主要介绍Web API的主要功能以及与其他同类型框架的对比,最后通过一些相对复杂的实例展示如何通过Web API构建http服务,同时也展示了Visual Studio构建.net项目的各种强大。

    目录

    什么是 Web API

    官方定义如下,强调两个关键点,即可以对接各种客户端(浏览器,移动设备),构建http服务的框架。

    ASP.NET Web API is a framework that makes it easy to build HTTP services that reach a broad range of clients, including browsers and mobile devices. ASP.NET Web API is an ideal platform for building RESTful applications on the .NET Framework.

    Web API在ASP.NET完整框架中地位如下图,与SignalR一起同为构建Service的框架。Web API负责构建http常规服务,而SingalR主要负责的是构建实时服务,例如股票,聊天室,在线游戏等实时性要求比较高的服务。

    Picture20

     

    为什么要用 Web API

    Web API最重要的是可以构建面向各种客户端的服务。另外与WCF REST Service不同在于,Web API利用Http协议的各个方面来表达服务(例如 URI/request response header/caching/versioning/content format),因此就省掉很多配置。

    Picture2

     

    当你遇到以下这些情况的时候,就可以考虑使用Web API了。

    • 需要Web Service但是不需要SOAP
    • 需要在已有的WCF服务基础上建立non-soap-based http服务
    • 只想发布一些简单的Http服务,不想使用相对复杂的WCF配置
    • 发布的服务可能会被带宽受限的设备访问
    • 希望使用开源框架,关键时候可以自己调试或者自定义一下框架

    功能简介

    Web API的主要功能

    1. 支持基于Http verb (GET, POST, PUT, DELETE)的CRUD (create, retrieve, update, delete)操作

        通过不同的http动作表达不同的含义,这样就不需要暴露多个API来支持这些基本操作。

    2. 请求的回复通过Http Status Code表达不同含义,并且客户端可以通过Accept header来与服务器协商格式,例如你希望服务器返回JSON格式还是XML格式。

    3. 请求的回复格式支持 JSON,XML,并且可以扩展添加其他格式。

    4. 原生支持OData

    5. 支持Self-host或者IIS host。

    6. 支持大多数MVC功能,例如Routing/Controller/Action Result/Filter/Model Builder/IOC Container/Dependency Injection。

    Web API vs MVC

    你可能会觉得Web API 与MVC很类似,他们有哪些不同之处呢?先上图,这就是他们最大的不同之处。

    Picture1

    详细点说他们的区别,

    • MVC主要用来构建网站,既关心数据也关心页面展示,而Web API只关注数据
    • Web API支持格式协商,客户端可以通过Accept header通知服务器期望的格式
    • Web API支持Self Host,MVC目前不支持
    • Web API通过不同的http verb表达不同的动作(CRUD),MVC则通过Action名字表达动作
    • Web API内建于ASP.NET System.Web.Http命名空间下,MVC位于System.Web.Mvc命名空间下,因此model binding/filter/routing等功能有所不同
    • 最后,Web API非常适合构建移动客户端服务

    Web API vs WCF

    发布服务在Web API和WCF之间该如何取舍呢?这里提供些简单地判断规则,

    • 如果服务需要支持One Way Messaging/Message Queue/Duplex Communication,选择WCF
    • 如果服务需要在TCP/Named Pipes/UDP (wcf 4.5),选择WCF
    • 如果服务需要在http协议上,并且希望利用http协议的各种功能,选择Web API
    • 如果服务需要被各种客户端(特别是移动客户端)调用,选择Web API

    Web API 实战 (Web API + MongoDB + knockoutjs)

    ASP.NET网站上有很多简单的Web API实例,看看贴图和实例代码你就明白怎么用了。这里我们通过一个稍微复杂一点的实例来展示下Web API的功能。

    涉及技术

    在我们的实例里面用到了:

    服务URI Pattern

    ActionHttp verbURI
    Get contact listGET/api/contacts
    Get filtered contactsGET/api/contacts?$top=2
    Get contact by IDGET/api/contacts/id
    Create new contactPOST/api/contacts
    Update a contactPUT/api/contacts/id
    Delete a contactDELETE/api/contacts/id

    准备工作

    1. 下载并安装Mongo DB,步骤看这里

    2. Mongo DB C# driver下载可以在nuget搜索mongocsharpdriver。

    3. 如果想本地察看数据库中内容,下载MongoVUE

    4. Knockoutjs下载可以在nuget搜索knockoutjs。

    代码实现

    1. 创建项目

    创建MVC4 Web Application

    1

    在Project Template中选择Web API

    2

    然后项目就创建成了,Controllers里面有一个ValuesController,是自动生成的一个最简单的Web API Controller。

    正如我们前面所说,里面引用的是System.Web.Http命名空间。

    3

    2. 创建model

    在model里面添加Contact类

    4

    代码如下,其中BsonId需要mongocsharpdriver。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class Contact
        {
            [BsonId]
            public string Id { get; set; }
            public string Name { get; set; }
            public string Phone { get; set; }
            public string Email { get; set; }
            public DateTime LastModified { get; set; }
        }

    我们需要添加mongosharpdriver。

    7

    8

    另外我们需要在Model中添加Repository,Controller通过该类来访问Mongo DB。

    1
    2
    3
    4
    5
    6
    7
    public interface IContactRepository {
            IEnumerable GetAllContacts();
            Contact GetContact(string id);
            Contact AddContact(Contact item);
            bool RemoveContact(string id);
            bool UpdateContact(string id, Contact item);  
        }

    ContactRepository的完整实现如下,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    public class ContactRepository : IContactRepository
        {
            MongoServer _server = null;
            MongoDatabase _database = null;
            MongoCollection _contacts = null;
     
            public ContactRepository(string connection)
            {
                if (string.IsNullOrWhiteSpace(connection))
                {
                    connection = "mongodb://localhost:27017";
                }
     
                _server = new MongoClient(connection).GetServer();
                _database = _server.GetDatabase("Contacts");
                _contacts = _database.GetCollection("contacts");
     
                // Reset database and add some default entries
                _contacts.RemoveAll();
                for (int index = 1; index < 5; index++)
                {
                    Contact contact1 = new Contact
                    {
                        Email = string.Format("test{0}@example.com", index),
                        Name = string.Format("test{0}", index),
                        Phone = string.Format("{0}{0}{0} {0}{0}{0} {0}{0}{0}{0}", index)
                    };
                    AddContact(contact1);
                }
            }
     
            public IEnumerable GetAllContacts()
            {
                return _contacts.FindAll();
            }
     
            public Contact GetContact(string id)
            {
                IMongoQuery query = Query.EQ("_id", id);
                return _contacts.Find(query).FirstOrDefault();
            }
     
            public Contact AddContact(Contact item)
            {
                item.Id = ObjectId.GenerateNewId().ToString();
                item.LastModified = DateTime.UtcNow;
                _contacts.Insert(item);
                return item;
            }
     
            public bool RemoveContact(string id)
            {
                IMongoQuery query = Query.EQ("_id", id);
                WriteConcernResult result = _contacts.Remove(query);
                return result.DocumentsAffected == 1;
            }
     
            public bool UpdateContact(string id, Contact item)
            {
                IMongoQuery query = Query.EQ("_id", id);
                item.LastModified = DateTime.UtcNow;
                IMongoUpdate update = Update
                    .Set("Email", item.Email)
                    .Set("LastModified", DateTime.UtcNow)
                    .Set("Name", item.Name)
                    .Set("Phone", item.Phone);
                WriteConcernResult result = _contacts.Update(query, update);
                return result.UpdatedExisting;
            }
        }

    3. 添加Controller

    右键Controllers目录选择添加Controller

    5

    选择Empty API controller,将Controller命名为ContactsController

    6

    添加如下代码,可以看到Controller中的API方法名就是以http verb命名的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    public class ContactsController : ApiController
        {
            private static readonly IContactRepository _contacts = new ContactRepository(string.Empty);
     
            public IQueryable Get()
            {
                return _contacts.GetAllContacts().AsQueryable();
            }
     
            public Contact Get(string id)
            {
                Contact contact = _contacts.GetContact(id);
                if (contact == null)
                {
                    throw new HttpResponseException(HttpStatusCode.NotFound);
                }
     
                return contact;
            }
     
            public Contact Post(Contact value)
            {
                Contact contact = _contacts.AddContact(value);
                return contact;
            }
     
            public void Put(string id, Contact value)
            {
                if (!_contacts.UpdateContact(id, value))
                {
                    throw new HttpResponseException(HttpStatusCode.NotFound);
                }
            }
     
            public void Delete(string id)
            {
                if (!_contacts.RemoveContact(id))
                {
                    throw new HttpResponseException(HttpStatusCode.NotFound);
                }
            }
        }

    4. 添加View

    首先添加Knockoutjs库,

    9

    Knockoutjs通过MVVM模式来实现动态html绑定数据,如下图,其中View-Model是客户端的javascript object保存的model数据。

    webapi_ef16

    先打开HomeController,里面添加一个新的Action代码如下,因为我们要在MVC中对于ContactsController添加对应的View。

    1
    2
    3
    4
    5
    6
    7
    public ActionResult Admin()
            {
                string apiUri = Url.HttpRouteUrl("DefaultApi", new { controller = "contacts", });
                ViewBag.ApiUrl = new Uri(Request.Url, apiUri).AbsoluteUri.ToString();
     
                return View();
            }

    然后右键Admin方法,选择添加View

    10

    选择Create strongly-typed view,在model class中选择Contact类。

    11

    添加View的完整代码,注意view中我们通过js去访问WebAPI,以及通过动态绑定将数据呈现在网页上。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    @model WebAPIDemo.Models.Contact
     
    @{
        ViewBag.Title = "Admin";
    }
     
    @section Scripts {
      @Scripts.Render("~/bundles/jqueryval")
      <script type="text/javascript" src="@Url.Content("~/Scripts/knockout-2.3.0.js")"></script>
      <script type="text/javascript">
          function ProductsViewModel() {
              var self = this;
              self.products = ko.observableArray();
     
              var baseUri = '@ViewBag.ApiUrl';
     
              self.create = function (formElement) {
                  // If valid, post the serialized form data to the web api
                  $(formElement).validate();
                  if ($(formElement).valid()) {
                      $.post(baseUri, $(formElement).serialize(), null, "json")
                          .done(function (o) { self.products.push(o); });
                  }
              }
     
              self.update = function (product) {
                  $.ajax({ type: "PUT", url: baseUri + '/' + product.Id, data: product });
              }
     
              self.remove = function (product) {
                  // First remove from the server, then from the UI
                  $.ajax({ type: "DELETE", url: baseUri + '/' + product.Id })
                      .done(function () { self.products.remove(product); });
              }
     
              $.getJSON(baseUri, self.products);
          }
     
          $(document).ready(function () {
              ko.applyBindings(new ProductsViewModel());
          })
      </script>
    }
     
    <h2>Admin</h2>
    <div class="content">
        <div class="float-left">
        <ul id="update-products" data-bind="foreach: products">
     
            <li>
                <div>
                    <div class="item">ID</div> <span data-bind="text: $data.Id"></span>
                </div>
                <div>
                    <div class="item">Name</div>
                    <input type="text" data-bind="value: $data.Name"/>
                </div>
                <div>
                    <div class="item">Phone</div>
                    <input type="text" data-bind="value: $data.Phone"/>
                </div>
                <div>
                    <div class="item">Email</div>
                    <input type="text" data-bind="value: $data.Email"/>
                </div>
                <div>
                    <div class="item">Last Modified</div> <span data-bind="text: $data.LastModified"></span>
                </div>
                <div>
                    <input type="button" value="Update" data-bind="click: $root.update"/>
                    <input type="button" value="Delete Item" data-bind="click: $root.remove"/>
                </div>
            </li>
        </ul>
        </div>
     
        <div class="float-right">
        <h2>Add New Product</h2>
        <form id="addProduct" data-bind="submit: create">
            @Html.ValidationSummary(true)
            <fieldset>
                <legend>Contact</legend>
                @Html.EditorForModel()
                <p>
                    <input type="submit" value="Save" />
                </p>
            </fieldset>
        </form>
        </div>
    </div>

    接下来在_layout.cshtml中添加一个admin页面的链接如下

    1
    2
    3
    4
    <ul id="menu">
        <li>@Html.ActionLink("Home", "Index", "Home", new { area = "" }, null)</li>
        <li>@Html.ActionLink("API", "Index", "Help", new { area = "" }, null)</li>
        <li>@Html.ActionLink("Admin", "Admin", "Home")</li>
     
    </ul>

    5. 测试与调试

    大功告成,直接运行下我们的作品,我们的admin链接也显示在右上角,

    12

    Admin页面的样子,Contact list是动态加载进来的,可以通过这个页面做添加,修改,删除的操作。

    13

    通过IE network capture来查看请求内容,

    重新加载页面,可以看到回复的格式为JSON,

    14

    JSON内容就是我们mock的一些数据。

    image

    接下来我们修改,删除,又添加了一条记录,可以看到使用了不同的http method。

    image

    通过前面安装的mongovue来查看下DB种的数据,先添加的user也在其中,令我感到欣慰。。。

    image


    原文链接:https://www.cnblogs.com/guyun/p/4589115.html


    展开全文
  • WebApi 基础+进阶 实战视频教程,整个课程分为两个阶段,基础和进阶(提高)阶段,两个阶段都会在讲解理论的同时提供一些相关示例,带着大家实战实操,在此过程中,由入门到进阶,由简单至复杂,循序渐进的掌握 ...
  • APIWeb API的概念

    千次阅读 2018-10-31 18:28:20
    APIWeb API的概念 API的概念 API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或...
  • WebAPI 实例

    热门讨论 2014-04-14 21:40:21
    webAPI 示例,webAPI 增加 修改 删除
  • 如何在VS中创建基于.NET的后端应用程序,该应用程序使用C#语言从Web API中提取。让我们开始吧! 为服务器后端逻辑选择语言的问题是几乎每个开发人员最重要的问题之一,特别是对于初学者。目前已经有很多不同的语言...
  • WebApi的创建和简单实现(一)

    千次阅读 2019-06-03 14:38:43
    WebApi 1.what? 答: 对接各种客户端(浏览器,移动设备),构建http服务的框架 2.where? 答:部署在IIS中给外部应用提供数据 3.why? 答:C#MVC完美支持实现简单,明了,可控制 一、创建WebApi 1、开发环境:vs...
  • vs2017开发web api 应用学习笔记

    千次阅读 2018-12-07 10:38:29
    参考网址:...在vs2017中选择新建项目-选择asp.net web 应用程序,在如下图示项目选择窗口中,选择“空“项目,勾选 Web Api,确定后系统自动创建空的Web Api项目; 二、设置路由 默...
  • Web Api 创建及其使用

    万次阅读 2019-01-21 20:25:00
    由于创建博客,我需要尝试一些新的技术,新的思路,所以我没规规矩矩的写博客,用上了诸多以前没用的东西,比如现在这个(我只是听过webapi我连webserver都只是用过两三次/手动滑稽) 昨天开始研究的,一直到现在,...
  • WebAPI搭建(一)

    万次阅读 2018-06-26 11:33:04
    选择webapi创建完成以后可以看到如下界面:3.找到App_Start文件夹下的WebApiConfig,将内容改为以下内容:public static void Register(HttpConfiguration config) { // Web API 配置和服务 // Web API 路由 .....
  • 上一节我们创建了基于Razor Page的简单应用,如果我们希望创建单页面应用或者移动应用,就需要通过Web Api调用应用层。Abp提供了从应用层到Web Api的自动映射,我们只需要增加少量的代码就可以,不需要编写重复的Api...
  • public class IOCController : ApiController { private IUserService _UserService = null; public IOCController(IUserService userService) { this._UserService = userService; } public string Get(int ...
  • (精华)2020年9月22日 微服务 WebAPI详解

    万次阅读 2020-09-07 23:05:13
    if (!(Test-Path -Path $PROFILE)) { New-Item -ItemType File -Path $PROFILE -Force }
  • WebApi路由机制详解——看完不会用你打我

    万次阅读 多人点赞 2018-11-12 00:25:04
    随着前后端分离的大热,WebApi在项目中的作用也是越来越重要,由于公司的原因我之前一直没有机会参与前后端分离的项目,但WebApi还是要学的呀,因为这东西确实很有用,可单独部署、与前端和App交互都很方便,既然有...
  • WebApi和访问WebApi两个项目

    千次下载 热门讨论 2014-12-05 15:08:48
    WebApi和访问WebApi两个项目,有源码,注释非常详细,希望对大家有帮助。 HttpWebRequest类访问webApi
  • Web API系列教程】1.1 — ASP.NET Web API入门

    万次阅读 多人点赞 2016-02-24 18:48:01
    前言HTTP不仅仅服务于web页面,同时也是构建暴露服务和数据的API的强大平台。...ASP.NET Web API是一个在.NET框架上构建web API的框架。在本教程中,你将使用ASP.NET Web API来创建一个返回产品列表的we
  • 2013年新书,学习ASP.NET Web API 现阶段最权威的一本专业教材; 前置技能:C#(掌握) , MVC(掌握或了解) ,数据库(掌握),HTML(掌握) 学会后能做: 多客户端(android,ios,web,win等)项目的共同Web服务器端,...
  • C# 搭建一个简单的WebApi项目

    万次阅读 多人点赞 2017-10-19 15:10:30
    一、创建Web API1、创建一个新的web API项目启动VS 2013,并在“开始页”选择“新项目”。或从“文件”菜单选择“新建”,然后选择“项目”。在“模板”面板中选择“已安装模板”,并展开“Visual C#”节点。选择该...
  • WebAPI学习(一)——创建Web API程序

    万次阅读 热门讨论 2016-03-13 14:59:50
    在公司中用到的都是webAPI的应用程序,这个东西之前没有接触过。但是这个并不是什么新鲜的东西,因我们 之前有mvc的基础,所以说学习这个东西还是比较容易的,在开始的时候自己可能突然蒙圈了。因为在人家项目中用 ...
  • WebApi和访问WebApi两个项目:多一些方法,封装方法,代码更加简洁,易懂
  • webAPI文档

    2016-07-31 15:49:50
    jdk,xpath,jsp,servlet,mysql,js,jquery,dom4j,正则表达式等api.chm, web开发涉及的大部分api都有了,方便web开发使用!
  • ASP.NET Web API详解

    千次阅读 2014-02-23 10:52:13
    在这篇文章中我们将讨论Web API设计、概念、功能,和对比Web API与WCF。 1. 实现一个Web API项目 我们从一个简单的实例开始讨论。我们使用Visual Studio 2012做为开发环境。我们第一步是基于Web API模版创建...
  • 备注:想要了解关于路由的高层次概述,请查看Routing in ASP.NET Web API。这篇文章侧重于路由过程的细节。如果你创建了一个Web API项目并且发现一些请求并没有按你预期得到相应的路由,希望这篇文章有所帮助。路由...
  • 1、基于ASP.NET MVC4.0 + WebAPI + EasyUI + Knockout的架构设计开发 2、采用MVC的框架模式,具有耦合性低、重用性高、生命周期成本低、可维护性高、有利软件工程化管理等优点 3、采用WebAPI,客户端完全摆脱了代理...
  • WebApi的几种寄宿方式

    千次阅读 2015-07-18 00:54:06
    ASP.NET Web API具有与ASP.NET MVC类似的编程方式,相关内容较少,如下通过一个实例讲解WebApi的集中寄宿方式。  目录  构建解决方案  定义Web API  以Web Host方式寄宿Web API  以Self Host方式寄宿Web...
  • 使用ASP.NET Web API构建Restful API

    千次阅读 2018-12-10 22:50:03
    目录 介绍 这种方法有什么好处? Restful约定 构建API ...在本文中,我们将构建测试并使用asp.net web api。 介绍 让我们快速回顾一下ASP.NET MVC架构。因此,当请求到达我们的应用程序时,MVC F...
  • WebAPI接口调试技巧

    千次阅读 2017-09-05 17:01:45
    1.了解WebAPI接口 接口模式:基于MVC4.0的WebAPI 承载协议:HTTP 跟踪工具:IE11 请求方式:POST 请求URL:IP:Port/Application/Controller/ActionName/Parameters 请求参数:一串由JSON对象转化而成的字符串 响应...
  • Android 调用WebAPI

    千次阅读 2014-08-28 15:21:03
    准备工作 gson-2.1的下载地址如下 ... 上文中我们已经下载了gson-2.1.jar,下载后如何调用,这个问题对Android高手是多余的,但是很多新手应该还是需要讲解一下的 首先我们将gson-2.1.jar粘贴到项目的“libs”目录下...

空空如也

1 2 3 4 5 ... 20
收藏数 821,488
精华内容 328,595
关键字:

webapi