前端技术演进(二):前端与协议

这个来自以前作的培训,删减了一些业务相关的,参考了不少资料( 参考资料列表),谢谢前辈们,么么哒 😘

目前先后端的通讯通常都是经过协议来完成的,这里介绍和前端开发相关的各种协议。javascript

HTTP

HTTP 协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是万维网的数据通讯的基础。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法,如今基本上什么类型的文件均可以传输了,好比图片、CSS、JS、数据报文等。html

HTTP通常基于TCP/IP通讯协议来传递数据,它有以下特色:前端

  1. 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法经常使用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不一样。因为HTTP协议简单,使得HTTP服务器的程序规模小,于是通讯速度很快。
  2. 灵活:HTTP容许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
  3. 无链接:无链接的含义是限制每次链接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开链接。采用这种方式能够节省传输时间。
  4. 无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺乏状态意味着若是后续处理须要前面的信息,则它必须重传,这样可能致使每次链接传送的数据量增大。另外一方面,在服务器不须要先前信息时它的应答就较快。
  5. 支持B/S及C/S模式。

HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和创建链接。URL是一种特殊类型的URI,包含了用于查找某个资源的足够的信息。一个完整的URL通常包括如下几部分:html5

协议 域名 端口 虚拟目录 文件名 参数 java

好比:http://test.google.com:80/test/test.html?query=admin#homegit

请求消息Request

一般一个HTTP请求消息包含以下内容:请求行、请求头、空行、消息主体。程序员

image.png | center | 466x165

好比:github

GET /books/?sex=man&name=Professional HTTP/1.1
 Host: www.example.com
 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
 Gecko/20050225 Firefox/1.0.1
 Connection: Keep-Alive
复制代码
  • 请求行:GET /books/?sex=man&name=Professional HTTP/1.1 用来讲明请求类型,要访问的资源以及所使用的HTTP版本。比较常见的请求类型有GET,POST,PUT,DELETE,OPTIONS等。
  • 请求头:从第二行起为请求头部,用来讲明服务器要使用的附加信息。
  • 空行:请求头部后面的空行是必须的,即便请求数据为空,也必须有空行。
  • 请求数据:也叫请求主体,能够添加任意的其余数据,这个例子的请求数据为空。

带有请求数据的POST请求:web

POST / HTTP/1.1
 Host: www.example.com
 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
 Gecko/20050225 Firefox/1.0.1
 Content-Type: application/x-www-form-urlencoded
 Content-Length: 40
 Connection: Keep-Alive

 sex=man&name=Professional  复制代码

响应消息Response

通常状况下,服务器接收并处理客户端发过来的请求后会返回一个HTTP的响应消息。一般一个HTTP请求消息包含以下内容:状态行、消息报头、空行、响应正文。typescript

好比:

HTTP/1.1 200 OK
Date: Fri, 22 May 2009 06:07:21 GMT
Content-Type: text/html; charset=UTF-8

<html>
      <head></head>
      <body>
            <!--body goes here-->
      </body>
</html>复制代码
  • 状态行:由HTTP协议版本号, 状态码, 状态消息 三部分组成。
  • 消息报头:用来讲明客户端要使用的一些附加信息。
  • 空行:消息报头后面的空行是必须的。
  • 响应正文,服务器返回给客户端的文本信息。

状态码

状态码由三位数字组成,第一个数字定义了响应的类别,共分五种类别:

  • 1xx:指示信息--表示请求已接收,继续处理。
  • 2xx:成功--表示请求已被成功接收、理解、接受。
  • 3xx:重定向--要完成请求必须进行更进一步的操做。
  • 4xx:客户端错误--请求有语法错误或请求没法实现。
  • 5xx:服务器端错误--服务器未能实现合法的请求。

常见的状态码有以下几种:

  • 200 OK 客户端请求成功。
  • 301 Moved Permanently 请求永久重定向。
  • 302 Moved Temporarily 请求临时重定向。
  • 304 Not Modified 文件未修改,能够直接使用缓存的文件。
  • 400 Bad Request 因为客户端请求有语法错误,不能被服务器所理解。
  • 401 Unauthorized 请求未经受权。
  • 403 Forbidden 服务器收到请求,可是拒绝提供服务。服务器一般会在响应正文中给出不提供服务的缘由。
  • 404 Not Found 请求的资源不存在,例如,输入了错误的URL。
  • 500 Internal Server Error 服务器发生不可预期的错误,致使没法完成客户端的请求。
  • 503 Service Unavailable 服务器当前不可以处理客户端的请求,在一段时间以后,服务器可能会恢复正常。

HTTP和TCP/IP协议的关系

image.png | left | 827x1208

HTTP/2

HTTP2即超文本传输协议2.0版本,是HTTP协议的下一个版本。由于标准委员会不打算再发布子版本了,因此直接叫HTTP/2,而不叫HTTP/2.0。

HTTP2相对于以前的HTTP协议有如下几个优势:

  • HTTP 2采用彻底二进制的格式来传输数据。同时HTTP 2对消息头采用HPACK压缩传输,最大限度地节省了传输带宽。相比于HTTP 1.x 每次请求都会携带大量冗余头信息(例如浏览器Cookie信息等),HTTP2具备很大的优点。
  • HTTP 2使用TCP多路复用的方式来下降网络请求链接创建和关闭的开销,多个请求能够经过一个TCP链接来并发完成。
  • HTTP2支持传输流的优先级和流量控制机制。HTTP2中每一个文件传输流都有本身的传输优先级,并能够经过服务器来动态改变,服务器会保证优先级高的文件流先传输。例如在将来的浏览器端渲染中,服务器端就能够优先传输CSS文件保证页面的渲染,而后在CSS文件所有传输完成后加载JavaScript脚本文件。
  • 支持服务器端推送。服务端可以在特定条件下把资源主动推送给客户端。

HTTP 1.1会让资源排队加载,以下图所示:

image.png | center | 720x319

但当咱们开启了HTTP/2以后,有了TCP多路复用,个数几乎没有限制了,以下图所示:

image.png | center | 720x571

HTTP/2 将 HTTP 协议通讯分解为二进制编码帧的交换,这些帧对应着特定数据流中的消息。全部这些都在一个 TCP 链接内复用。这是 HTTP/2 协议全部其余功能和性能优化的基础。

image.png | center | 827x645

目前支持HTTP2协议传输的浏览器依然不多,随着技术的发展和浏览器的更新迭代,HTTP2的时代终会到来,但咱们依然不能在短期内企图经过它来帮咱们进行页面优化。

HTTPS

HTTPS(超文本传输安全协议 Hypertext Transfer Protocol Secure)经由HTTP进行通讯,但利用SSL/TLS来加密数据包。HTTPS的主要思想是在不安全的网络上建立一安全信道。一般,HTTP 直接和 TCP 通讯。当使用 SSL 时,则演变成先和 SSL 通讯,再由 SSL 和 TCP 通讯了。简言之,所谓 HTTPS,其实就是身披 SSL 协议这层外壳的 HTTP。HTTP的URL由“http://”起始且默认使用端口80,HTTPS的URL由“https://”起始且默认使用端口443。

SSL 是独立于 HTTP 的协议,因此不光是 HTTP 协议,其余运行在应用层的 SMTP 和 Telnet 等协议都可配合 SSL(Secure Socket Layer) 协议使用。

image.png | center | 342x157

HTTP是不安全的,攻击者经过监听和中间人攻击等手段,能够获取网站账户和敏感信息等。人们对 HTTPS 有一个广泛的错误认识,认为只有处理敏感通讯的网站才须要 HTTPS。 每一个未受保护的 HTTP 请求均可能暴露与用户行为和身份有关的信息。尽管访问一次未受保护的网站可能看上去无害,但一些入侵者会查看汇总的用户浏览活动,以推断他们的行为和意图,从而进行去匿名化攻击,查出匿名用户的身份。例如,员工可能在阅读未受保护的医疗文章时不经意地向其雇主泄露敏感的健康信息。

公钥和私钥

加密和解密同用一个密钥的方式称为共享密钥加密(Common key crypto system),也被叫作对称密钥加密。

image.png | center | 600x456.23632385120345

以共享密钥方式加密时必须将密钥也发给对方。可究竟怎样才能安全地转交?在互联网上转发密钥时,若是通讯被监听那么密钥就可会落入攻击者之手,同时也就失去了加密的意义。

SSL 采用一种叫作公开密钥加密(Public-key cryptography)的加密处理方式。公开密钥加密使用一对非对称的密钥。一把叫作私有密钥(private key),另外一把叫作公开密钥(public key)。顾名思义,私有密钥不能让其余任何人知道,而公开密钥则能够随意发布,任何人均可以得到。

使用公开密钥加密方式,发送密文的一方使用对方的公开密钥进行加密处理,对方收到被加密的信息后,再使用本身的私有密钥进行解密。利用这种方式,不须要发送用来解密的私有密钥,也没必要担忧密钥被攻击者窃听而盗走。

image.png | center | 600x464.6080760095012

HTTPS 采用混合加密机制:

image.png | center | 600x538.3863080684596

证书颁发机构

公开密钥加密方式仍是存在一些问题的。那就是没法证实公开密钥自己就是货真价实的公开密钥。

证书颁发机构 (CA) 是一个组织,对公钥和与公共 DNS 名称之间的映射进行证明。例如,客户端如何知道特定公钥是否为 www.foobar.com 的真实公钥?按理说,没法知道。CA 证明特定密钥是特定网站的真实密钥,它使用本身的私钥来加密签名该网站的公钥。此签名在计算上是没法伪造的。浏览器(和其余客户端)维护信任锚存储库,它包含知名 CA 拥有的公钥,而且它们使用这些公钥来加密验证 CA 的签名。

SSL握手流程

image.png | center | 827x886

最后使用共享密钥来进行之后的通讯,详细流程:

image.png | center | 827x1564

Websocket

在实际的前端应用项目中,除了使用应答模式的HTTP协议进行普通网络资源文件的请求加载外,有时也须要创建客户端与服务端之间的实时链接进行通讯,例如网页实时聊天的应用场景,这就必须涉及浏览器端的实时通讯协议了。对于这些对实时性要求较高的应用场景,普通的HTTP协议就并不适用。虽然前端能够经过Ajax定时向服务端轮询的方式来持续获取服务端的消息,可是这种方式效率相对较低。

WebSocket是浏览器端和服务器端创建实时链接的一种通讯协议,能够在服务器和浏览器端创建相似Socket方式的消息通讯。相对于HTTP1.1协议,WebSocket协议的优点是方便服务器和浏览器之间的双向数据实时通讯。

7层网络模型

这里只是相似Socket方式,WebSocket 是创建在 TCP/IP 协议之上,属于应用层的协议,而 Socket 是在应用层和传输层中的一个抽象层,它是将 TCP/IP 层的复杂操做抽象成几个简单的接口来提供给应用层调用。简单回顾一下7层网络模型:

image.png | center | 827x586

简单来讲,咱们在传输数据时,能够只使用(传输层)TCP/IP协议,可是那样的话,若是没有应用层,便没法识别数据内容。若是想要使传输的数据有意义,则必须使用到应用层协议。应用层协议有不少,好比HTTP、FTP、TELNET等,也能够本身定义应用层协议。WEB使用HTTP协议做应用层协议,以封装HTTP文本信息,而后使用TCP/IP作传输层协议将它发到网络上。

TCP/IP只是一个协议栈,就像操做系统的运行机制同样,必需要具体实现,同时还要提供对外的操做接口。这个就像操做系统会提供标准的编程接口,好比win32编程接口同样,TCP/IP也要提供可供程序员作网络开发所用的接口,这就是Socket编程接口。Socket的出现只是使得程序员更方便地使用TCP/IP协议栈而已,是对TCP/IP协议的抽象,从而造成了咱们知道的一些最基本的函数接口,好比create、listen、connect、accept、send、read和write等等。

image.png | center | 827x1172

Websocket使用

WebSocket 的实现分为握手,数据发送/读取,关闭链接。

image.png | center | 827x505

var ws = new WebSocket("wss://echo.websocket.org");

ws.onopen = function(evt) { 
  console.log("Connection open ..."); 
  ws.send("Hello WebSockets!");
};

ws.onmessage = function(evt) {
  console.log( "Received Message: " + evt.data);
  ws.close();
};

ws.onclose = function(evt) {
  console.log("Connection closed.");
};      复制代码

在线演示:html5demos.com/web-socket/

DDP

DDP ( Distributed Data Protocol,分布式数据协议)是一种新型的客户端与服务器端的实时通讯协议,因为兼容性的缘由,目前使用还不普遍。

DDP使用JSON的数据格式在客户端和浏览器之间进行数据传输通讯,因此对于前端开发者来讲使用很是方便。有名的Meteor Web框架的双向实时数据更新机制底层使用的就是DDP,这种协议模式下客户端可向服务器端发起远程过程调用,客户端也能够订阅服务端数据,在服务端数据变化时,服务器会向客户端发起通知,触发浏览器响应的操做。

//建立服务端
const DDPClient = require('ddp');
const client = new DDPClient({
  host: 'localhost',
  port: 3000
});

//监听消息
client.on('message', function(data, flags){
  console.log('[DDP消息]: ', data);
});

//建立链接
client.connect(function(){
  client.subscribe('post',[],function(){
    console.log('[post订阅消息]');
  });
});复制代码

协议标准:github.com/meteor/mete…

RESTful

REST (Representational State Transfer,表述性状态转化)并非某一种具体的协议,而是定义了一种网络应用软件之间的架构关系并提出了一套与之对应的网络之间交互调用的规则。与之相似的例如早期的WebSevice,WebSevice如今基本都不用了。

在REST形式的软件应用服务中,每一个资源都有一个与之对应的URI地址,资源自己都是方法调用的目标,方法列表对全部资源都是同样的,并且这些方法都推荐使用HTTP协议的标准方法,例如GET、POST、PUT、DELETE等。若是一个网络应用软件的设计是按照REST定义的,咱们就能够认为它使用的交互调用的方法设计遵循RESTful规范。换种方式理解,RESTful 是一种软件架构之间交互调用数据的协议风格规范,它建议以一种通用的方式来定义和管理数据交互调用接口。

例如:对于书籍book的记录管理接口,有增、刪、改、查操做,因而咱们定义接口:

  • path/addBook
  • path/deleteBook
  • path/updateBook
  • path/getBook

看上去好像没有什么问题。后来,另外一个项目也有相似的接口定义,却可能叫做:

  • path/appendBook
  • path/delBook
  • path/modifyBook
  • path/getBook

接着有一天,项目负责人可能会说,要升级接口来知足新的需求,因而咱们又添加了:

  • path/addBook2
  • path/deleteBook2
  • path/updateBook2
  • path/getBook2

这样用起来是没有什么问题,可是这些随意的定义会增长数据接口维护难度和项目继续开发的成本。

这时,咱们或许会考虑使用文档或规范,规定必定要使用add来添加,新的接口版本号放前面 path/v2/addBook,开发的人必须严格按照文档规范去写。这样作很好,但依然不够完善,缘由有如下几点:

  • 由于项目工做经常排期紧张,你可能没时间去写文档,或者后面接手的人不想去看文档。
  • 开发修改功能后极可能来不及或忘记去更新文档。
  • 不管文档写得多清楚,咱们看起来效率老是很低。

这时若是有一个风格更好的通用规范来定义数据交互接口,就不用这么麻烦了。因此咱们彻底能够利用RESTful设计的规范特性来解决上面遇到的问题。对于书籍记录操做接口的命名能够以下操做:

HTTP方法 URI 描述
POST path/v1/book 新增书籍信息
DELETE path/v1/book 删除书籍信息
PUT path/v1/book 更新书籍信息
GET path/v1/book 获取书籍信息

使用RESTful规范来从新设计接口后,一切就变得很清晰天然,这样新的工程师接手项目时,只要他足够了解RESTful规范,几乎没有时间成本。即便他不了解RESTful规范,也能够很快地去了解,这就能够避免他去读那份看似完善其实冗长杂的文档。

这里涉及到了几个设计的原则:

  • “资源”表示一种实体,因此应该是名词,URL不该该有动词,动词应该放在HTTP协议中。
  • 按照标准,不该该在URL中包含版本号,应该放在HTTP请求头信息的Accept字段中,不过这样不够直观,因此通常的方式仍是把版本号放在URL中,算是一个反模式。

RESTful API 的主要设计原则就是这些,总结来讲就是结合HTTP的固有方式来表征资源的状态变化描述,而不是经过动词加名词的方式来设计。

Github RESTful API:developer.github.com/v3/

GraphQL

GraphQL 对 API 中的数据提供了一套易于理解的完整描述,使得客户端可以准确地得到它须要的数据,并且没有任何冗余,也让 API 更容易地随着时间推移而演进。

GraphQL 解决的最重要的3个问题分别是:

  • 须要进行屡次往返以获取所需的数据:典型的 REST API 请求多个资源时得载入多个 URL,而 GraphQL 能够经过一次请求就获取你应用所需的全部数据。
  • 客户端依赖于服务端:消除了服务器对数据内容进行硬编码的须要。咱们能够把客户端与服务端分离开来,单独进行维护和改进。先后端完全分离。
  • 糟糕的前端开发体验:使用 GraphQL,开发人员能够声明式地来表达其用户界面的数据需求,不用老是关注数据是如何获取的。

RESTful APIs vs GraphQL APIs

一个简单的示例:咱们要作一个星球大战人物信息展现的UI界面:须要显示人物的姓名,出生年份,星球名称以及全部他们参演的电影的名称。

这个 UI 的 JSON 数据可能相似于:

{
  "data": {
    "person": {
      "name": "Darth Vader",
      "birthYear": "41.9BBY",
      "planet": {
        "name": "Tatooine"
      },
      "films": [
        { "title": "A New Hope" },
        { "title": "The Empire Strikes Back" },
        { "title": "Return of the Jedi" },
        { "title": "Revenge of the Sith" }
      ]
    }
  }
}复制代码

若是使用 React.js ,通常会这样表示视图:

// The Container Component:
<PersonProfile person={data.person} ></PersonProfile>

// The PersonProfile Component:
Name: {person.name}
Birth Year: {person.birthYear}
Planet: {person.planet.name}
Films: {person.films.map(film => film.title)}复制代码

若是使用 RESTful API,咱们可能这样请求数据:

一、获取人物信息:

GET - /people/{id}复制代码
{
  "name": "Darth Vader",
  "birthYear": "41.9BBY",
  "planetId": 1
  "filmIds": [1, 2, 3, 6],
  ...
}复制代码

二、获取星球信息:

GET - /planets/1复制代码

三、获取全部电影信息:

GET - /films/1
GET - /films/2
GET - /films/3
GET - /films/6复制代码

演示

咱们须要发送6个请求才能获取到全部须要的数据,每一个获取数据的方法都是命令式的。每一个接口返回的信息还有不少字段不是咱们所须要的。为了解决这个问题,咱们可能会新增长一个接口,好比:

GET - /people/{id}/films复制代码

可是这样就不是纯粹的RESTful API了,并且后端要额外的建立这个接口,用来知足前端的数据要求,若是增减字段或对象,后端还要添加接口或者从新编码。

若是使用GraphQL,咱们能够这样来查询:

GET or POST - /graphql?query={...}复制代码

好比参数使用:

{
  person(personID: 4) {
    name,
    birthYear,
    homeworld {
      name
    },
    filmConnection {
      films {
        title
      }
    }
  }
}复制代码

演示

一个请求就完成了全部数据的获取。

GraphQL的灵活性也会带来一些问题,好比增长复杂度,资源耗尽攻击,N+1查询等。FB针对N+1给出了 dataloader 的方案。

Github GraphQL API:developer.github.com/v4/

在线调试:developer.github.com/v4/explorer…

与Native交互

Hybrid App是在Native App应用的基础上结合了Web App应用所造成的模式,通常称之为混合App。从技术开发上来看,相比于传统的桌面浏览器端的Web App,它具备如下几方面的特征:

  • 可用的系统网络资源更少。因为移动设备CPU、内存、网卡、网络链接多方面的限制,HybridApp的前端页面可用的系统资源远远小于桌面浏览器。就网络链接来讲,大部分移动设备的使用者使用的还是3G、4G的网络,带宽和流量均有限制,和桌面浏览器的带宽接入相比仍是有着本质上的区别。
  • 支持更新的浏览器特性。目前智能设备浏览器种类相对较少,且随着硬件设备的快速更新,主流的浏览器以WebKit内核居多,支持较新的浏览器特性。不像桌面浏览器那样须要考虑较低版本Internet Explorer的兼容性问题。
  • 可实现离线应用。Hybrid的一个优点是能够经过新的浏览器特性或Native的文件读取机制进行文件级的文件缓存和离线更新。这是桌面浏览器,上较难作到的。这些离线机制经常能够用来弥补Hybrid App网络系统资源不足的缺点,让浏览器脚本更快从本地缓存中加载。
  • 较多的机型考虑。因为目前移动设备平台不统一,并且不一样设备机型系统的浏览器实现仍有必定的区别,所以Hybrid App应用须要考虑不一样设备机型的兼容性问题。
  • 支持与Native交互。Hybrid App的另外一个特色是结合了移动端Native特性,能够在前端页面中调用客户端Native的能力,例如摄像头、定位、传感器、本地文件访问等。

Web调用Native

在HTML5中调用Native程序通常有几种较通用的方法:

1、经过URI请求。

Native应用可在移动端系统中注册一个Scheme协议的URI,这个URI可在系统的任意地方受权访问来调起一段原生方法或一个原生的界面。一样,Native 的WebView控件中的JavaScript脚本的请求也能够匹配调用这一通用的Scheme协议。例如咱们经过对 window.location.href 赋值或使用iframe的方式发送一个URI的请求,这个请求能够被Native应用的系统捕获并调起Native应用注册匹配的这个Scheme协议内容。

好比微信的scheme为(weixin://)。

image.png | center | 596x625

2、经过addJavascriptInterface(Android)或JavaScriptCore(iOS)注入方法到页面中调用。

Android,原生Webview须要先注册可供前端调用的JS函数:

// Android容器容许JS脚本,必需要
webSettings.setJavaScriptEnabled(true);
// Android容器设置侨连对象
mWebView.addJavascriptInterface(getJSBridge(), "JSBridge");

// Android4.2版本及以上,本地方法要加上注解@JavascriptInterface,不然会找不到方法。
private Object getJSBridge(){  
    Object insertObj = new Object(){  
        @JavascriptInterface
        public String foo(){  
            return "foo";  
        }  

        @JavascriptInterface
        public String foo2(final String param){  
            return "foo2:" + param;  
        }  

    };  
    return insertObj;  
}复制代码

而后H5中便可调用原生中注册的函数:

// 调用方法一
window.JSBridge.foo(); // 返回:'foo'
// 调用方法二
window.JSBridge.foo2('test'); // 返回:'foo2:test'复制代码

iOS,须要引入JavaScriptCore库:

#import <JavaScriptCore/JavaScriptCore.h>复制代码

而后原生须要注册API:

//webview加载完毕后设置一些js接口
-(void)webViewDidFinishLoad:(UIWebView *)webView{
    [self hideProgress];
    [self setJSInterface];
}

-(void)setJSInterface{

    JSContext *context =[_wv valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

    // 注册名为foo的api方法
    context[@"foo"] = ^() {

        //获取参数
        NSArray *args = [JSContext currentArguments];
        NSString *title = [NSString stringWithFormat:@"%@",[args objectAtIndex:0]];
        //作一些本身的逻辑
        //返回一个值  'foo:'+title
        return [NSString stringWithFormat:@"foo:%@", title];
    };
    
}复制代码

以后前端就能够调用了:

// 调用方法,用top是确保调用到最顶级,由于iframe要用top才能拿到顶级
window.top.foo('test'); // 返回:'foo:test'复制代码

3、改写浏览器原有对象。

经过修改原来浏览器的window某些方法,而后拦截固定规则的参数,而后分发给Java对应的方法去处理。这里经常使用的是如下四个方法:

  • alert,能够被webview的onJsAlert监听
  • confirm,能够被webview的onJsConfirm监听
  • console.log,能够被webview的onConsoleMessage监听
  • prompt,能够被webview的onJsPrompt监听

Native调用Web

须要先使用JavaScript 在HTML5页面全局中声明相对应的方法。

而后Native向HTML5发起调用,Android平台通常经过loadUrl,iOS一般经过stringByEvaluatingJavaScriptFromString实现。

Android调HTML5:

// 异步执行JS代码,并获取返回值    
mWebView.evaluateJavascript("javascript: 方法名('参数,须要转为字符串')", new ValueCallback<String>() {
        @Override
        public void onReceiveValue(String value) {
            // 这里的value即为对应JS方法的返回值
        }
});复制代码

iOS调HTML5:

// 能够取得JS函数执行的返回值
// 方法必须是Html页面绑定在最顶层的window上对象的
// 如window.top.foo
[webView stringByEvaluatingJavaScriptFromString:@"方法名(参数);"];复制代码

JSBridge

image.png | center | 690x167

JSBridge是HTML5与Native通讯的桥梁,其做用是实现HTML5与Native间的双向通讯。JSBridge综合了上面的技术,更多的是一种形式、一种思想,各家的实现方式也略有差别。好比微信JSSDK,就是基于WeixinJSBridge,微信浏览器中的页面,经过WeixinJSBridge调用微信提供的一些原生功能。

相关文章
相关标签/搜索