HTML5中的webSocket、ajax、http

本文原链接:https://cloud.tencent.com/developer/article/1115496

https://cloud.tencent.com/developer/article/1193011

webSocket与ajax、web

  • 一、webSocket与ajax
    • 1、ajax
    • 2、webSocket
  • 二、webSocket API
    • 1、事件
    • 2、方法
    • 3、属性
    • 4、常量
  • 三、webSocket与HTTP
  • 四、webSocket原理
  • 五、webSocket的作用
    • 1、ajax轮询:
    • 2、long poll
    • 3、webSocket
  • 六、Socket.io

先看一个有道释义:

其实释义的挺形象的,下面我来一一解释哈:

1、聊天室:webSocket有名的应用就是聊天室了;

2、服务:webSocket提供客户端请求的服务器和服务;

3、套接字:源IP地址和目的IP地址以及源端口号和目的端口号的组合叫套接字,webSocket就是服务端和客户端的结合;

4、协议:webSocket是基于TCP的一种新的网络协议。

一、webSocket与ajax

作为一个码了还算久代码的前端,说起webSocket,脑子里最先闪现的当然就是ajax ajax ajax......ajax是啥,ajax刚出来时,可谓轰动一时,让我们愉快地告别那种提交一个表单必须得填完所有信息,然后再把数据转给服务器验证,结果发现有一个小小的输入框里输错了信息,然后又改掉重新提交走着重复的路的痛苦时代,所以它最大的贡献就是局部刷新。当然,不是说有了webSocket,它就out了,ajax现在依旧好用。下面稍微比较了下ajax和webSocket:

1、ajax

(1)浏览器主动发送消息给服务器;

(2)非实时数据交互(异步,局部刷新)。

原生写法:

四部曲:ajax对象、建立连接、发送请求、获取相应

更通俗的用打电话来比喻,那就是:电话、拨号、说话、听到对方回应。demo

//创建一个ajax对象(想打电话,首先得有电话这个对象)
var XHR = null; if (window.XMLHttpRequest) { // 非IE内核 XHR = new XMLHttpRequest(); } else if (window.ActiveXObject) { // IE内核,早期IE的版本写法不同 XHR = new ActiveXObject("Microsoft.XMLHTTP"); } else { XHR = null; } 
if(XHR){ //建立连接(拨号) XHR.open("GET", "ajaxServer.action",true); //发送请求(说话) XHR.send(); //获取响应(听到对方回应) XHR.onreadystatechange = function () { // readyState值说明 // 0,初始化,XHR对象已经创建,还未执行open // 1,载入,已经调用open方法,但是还没发送请求 // 2,载入完成,请求已经发送完成 // 3,交互,可以接收到部分数据 
// 4,交互完毕 // status值说明 // 200:成功 // 404:没有发现文件、查询或URl // 500:服务器产生内部错误 if (XHR.readyState == 4 && XHR.status == 200) { // 这里可以对返回的内容做处理 // 一般会返回JSON或XML数据格式 console.log(XHR.responseText); // 主动释放,JS本身也会回收的 XHR = null; } }; }

JQuery写法(so easy,妈妈再也不用担心我的学习啦):

$.ajax({type:"post", url:url, async:true, data:params, dataType:"json", success:function(res){ console.log(res); }, error:function(jqXHQ){ alert("发生错误:"+jqXHQ.status); } });

 

2、webSocket

(1)实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端;

(2)实时数据交互。

WebSocket 握手过程
WebSocket 协议本质上是一个基于 TCP 的协议,WebSocket

连接与 TCP 连接的建立过程类似[4]。但与传统的基于 TCP 连 接的协议有所不同的是 WebSocket 协议需要从 HTTP 协议“过 渡”而来,而这个“过度”过程也被称为 WebSocket 协议的握手 过程。因此想要建立基于 WebSocket 的 Web 应用必须首先了解 WebSocket 协议的握手机制,如图 2 给出了 WebSocket 协议握手 过程的示意图。

首先由浏览器客户端向服务器发起 WebSocket 握手请求报 文,这个报文是基于 HTTP 协议的,它告诉服务器客户端想要升 级当前的 HTTP 协议为 WebSocket 协议。服务器收到客户端的 WebSocket 握手请求报文之后会对报头进行解析,如果服务器 理解客户端握手请求报头并且满足升级为 WebSocket 协议的条 件,便会向客户端发送握手应答报文,这个应答报文同样是基于 HTTP 协议的。客户端收到服务器的应答报文后会对该报文进 行一次验证,验证成功之后便会成功升级为 WebSocket 协议,如 果验证失败客户端将会主动断开连接。建立了 WebSocket 连接 之后,双方便可以进行全双工通信, 

WebSocket 握手过程与 TCP 握手过程类似,但是 WebSocket 协议握手采用了更加简洁的方式。

相对于传统的 TCP 握手,WebSocket 握手协议有以下明显 的特点: 首先,WebSocket 整个握手过程只需要两次握手,相对 于 TCP 的三次握手,WebSocket 简化并且加入了自己的规则。 其次,WebSocket 握手协议是基于 HTTP 协议的,相对于字节流 的解析,ASCII 序列解析起来更加简便。最后,WebSocket 握手 协议引入了随机序列认证机制,易于实现。

两次握手成功预示着双方接下来将升级当前的 HTTP 协议 为 WebSocket 协议。WebSocket 握手请求报文的报头部分除了 必须包含必要的 HTTP 字段[5],还须遵循通用消息格式[RFC 822],同时又要包含和 WebSocket 紧密联系的字段[6],如 Web- Socket 协议的版本信息、客户端随即生成的 Key、必要的 GET 请 求方法等。 

 

// Create WebSocket connection.
var socket = new WebSocket('ws://localhost:8080'); //创建一个webSocket实例 // Connection opened socket.addEventListener('open', function (event) { //一旦服务端响应WebSocket连接请求,就会触发open事件 socket.send('Hello Server!'); }); // Listen for messages socket.addEventListener('message', function (event) { //当消息被接受会触发消息事件 console.log('Message from server', event.data); });

 

二、webSocket API

既然上面写了一部分代码,那不如把API全都贴出来,哈哈哈。

首先,创建一个webSocket实例:

var socket = new WebSocket('ws://localhost:8080'); 

然后再看下面的的API。

1、事件

(1)open

一个用于连接打开事件的事件监听器。当readyState的值变为 OPEN 的时候会触发该事件。该事件表明这个连接已经准备好接受和发送数据。这个监听器会接受一个名为"open"的事件对象。

socket.onopen = function(e) { console.log("Connection open..."); };

或者:

socket.addEventListener('open', function (event) { console.log("Connection open..."); });

(2)message

一个用于消息事件的事件监听器,这一事件当有消息到达的时候该事件会触发。这个Listener会被传入一个名为"message"的 MessageEvent 对象。

socket.onmessage = function(e) { console.log("message received", e, e.data); };

(3)error

当错误发生时用于监听error事件的事件监听器。会接受一个名为“error”的event对象。

socket.onerror = function(e) { console.log("WebSocket Error: " , e); };

(4)close

用于监听连接关闭事件监听器。当 WebSocket 对象的readyState 状态变为 CLOSED 时会触发该事件。这个监听器会接收一个叫close的 CloseEvent 对象。

socket.onclose = function(e) { console.log("Connection closed", e); };

2、方法

(1)send

通过WebSocket连接向服务器发送数据。

一旦在服务端和客户端建立了全双工的双向连接,可以使用send方法去发送消息,当连接是open的时候send()方法传送数据,当连接关闭或获取不到的时候回抛出异常。

一个通常的错误是人们喜欢在连接open之前发送消息。如下所示:

// 这将不会工作
var socket= new WebSocket("ws://localhost:8080") socket.send("Initial data");

应该等待open事件触发后再发送消息,正确的姿势如下:

var socket= new WebSocket("ws://localhost:8080") socket.onopen = function(e) { socket.send("Initial data"); }

(2)close

关闭WebSocket连接或停止正在进行的连接请求。如果连接的状态已经是closed,这个方法不会有任何效果。

使用close方法来关闭连接,如果连接已经关闭,这方法将什么也不做。调用close方法后,将不能再发送数据。close方法可以传入两个可选的参数,code(numerical)和reason(string),以告诉服务端为什么终止连接。

socket.close(1000, "Closing normally"); //1000是状态码,代表正常结束。

 

3、属性

属性名

类型

描述

binaryType

DOMString

一个字符串表示被传输二进制的内容的类型。取值应当是"blob"或者"arraybuffer"。 "blob"表示使用DOMBlob 对象,而"arraybuffer"表示使用 ArrayBuffer 对象。

bufferedAmount

unsigned long

调用 send() 方法将多字节数据加入到队列中等待传输,但是还未发出。该值会在所有队列数据被发送后重置为 0。而当连接关闭时不会设为0。如果持续调用send(),这个值会持续增长。只读。

extensions

DOMString

服务器选定的扩展。目前这个属性只是一个空字符串,或者是一个包含所有扩展的列表。

protocol

DOMString

一个表明服务器选定的子协议名字的字符串。这个属性的取值会被取值为构造器传入的protocols参数。

readyState

unsigned short

连接的当前状态。取值是 Ready state constants之一。只读。

url

DOMString

传入构造器的URL。它必须是一个绝对地址的URL。只读。

4、常量

Ready state 常量

常量

描述

CONNECTING

0

连接还没开启。

OPEN

1

连接已开启并准备好进行通信。

CLOSING

2

连接正在关闭的过程中。

CLOSED

3

连接已经关闭,或者连接无法建立。

三、webSocket与HTTP

webSocket和http同为协议,大家心里肯定会想它俩之间有什么联系,当然,我也好奇,所以就有了下面的研究结果,呵呵呵呵~~

大家都知道,webSocket是H5的一种新协议(这样看来和http是没什么关系),本质是通过http/https协议进行握手后创建一个用于交换数据的TCP连接,服务端与客户端通过此TCP连接进行实时通信。也就是说,webSocket是http协议上的一种补充。

相对于HTTP这种非持久的协议来说,Websocket是一个持久化的协议。

以php的生命周期为例:

在http1.0中,一个request,一个response,一个周期就结束了。

在http1.1中,有了keep-alive,可以发送多个Request,接收多个Response。但在http中永远是一个request对应一个response。而且这个response是被动的,不能主动发起。

这时候webSocket就派上用场了。

四、webSocket原理

首先,先来看一张http的Request Headers:

再看一张webSocket的:

以及webSocket的Response Headers:

I guess,无论熟不熟悉http,想必都看出了区别,哈哈哈。接下来就要对这些东西进行讲解啦:

(1)Upgrade和Connection

Upgrade: websocket
Connection: Upgrade

这个就是webSocket的核心,告诉Apache、ngix等服务器:注意啦,我发起的是webSocket协议,快点帮我找到对应的助理处理~ 不是那个老土的http。

(2)Sec-WebSocket-Key、Sec-WebSocket-Extensions和Sec-WebSocket-Version

Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Extensions: chat, superchat Sec-WebSocket-Version: 13

这个很好理解啦,首先,Sec-WebSocket-Key是一个Base64 encode的值,这个是浏览器随机生成的,告诉服务器:尼好,我是webSocket,这是我的ID卡,让我过去吧。

然后,Sec-WebSocket-Extensions:协议扩展, 某类协议可能支持多个扩展,通过它可以实现协议增强

最后,Sec-WebSocket-Version是告诉服务器所使用的webSocket Draft(协议版本)。喏,我是小喵4.1版本哆啦A梦,哈哈哈哈哈哈哈哈。

然后只要服务器返回了上面我放的那一系列balabala的东西,就代表已经接受请求,webSocket建立成功啦!

(3)Sec-WebSocket-Accept和Sec-WebSocket-Extensions

请求时,webSocket会自带加密过的ID卡过来让服务端验证;

对应的,接受请求之后,服务端也得搞一个安全卡(Accept头域的值就是Key的值,是由浏览器发过来的Sec-WebSocket-Key生成的)来证明是我同意你通过的,而不是什么肯蒙拐骗的坏银->

就这样,原理部分就说完啦,握手成功!

五、webSocket的作用

说webSocket之前,先说一下ajax轮询和long poll。

1、ajax轮询:

ajax轮询很简单,就是让浏览器隔个几秒就发送一次请求,询问服务器是否有新信息。

客户端:hello hello,有没有新信息(Request)服务端:没有(Response)客户端:hello hello,有没有新信息(Request) 服务端:没有。。(Response) 客户端:hello hello,有没有新信息(Request) 服务端:你好烦啊,没有啊。。(Response) 客户端:hello hello,有没有新消息(Request) 服务端:有啦有啦,here you are(Response) 客户端:hello hello,有没有新消息(Request) 服务端:。。没。。。。没。。。没。。。。(Response)

 

2、long poll

long poll和ajax轮询原理很像,不过long poll是阻塞模型,简单来说,就是一直给你打电话,直到你接听为止。

客户端:hello hello,有没有新信息,没有的话就等有了再返回给我吧(Request)服务端:额。。。     (。。。。等待到有消息的时候。。。。)     有了,给你(Response)

很明显,ajax轮询和long poll弊大于利:

(1)被动性

上面这两种方式都是客户端先主动消息给服务端,然后等待服务端应答,要知道,等待总是难熬的,如果服务端能主动发消息多好,这也就是缺点之一:被动性。

(2)非常消耗资源

ajax轮询 需要服务器有很快的处理速度和资源(速度);

long poll 需要有很高的并发,也就是说同时接待客户的能力(场地大小)。

so,当ajax轮询和long poll碰上503(啊啊啊啊啊,game over)

这时候,神奇的webSocket又派上用场了。

 

3、webSocket

(1)被动性

首先,解决被动性:

客户端:hello hello,我要建立webSocket协议,扩展服务:chat,Websocket,协议版本:17(HTTP Request)服务端:ok,确认,已升级为webSocket协议(HTTP Protocols Switched)客户端:麻烦你有信息的时候推送给我噢。。服务端:ok,有的时候会告诉你的。服务端:balabalabalabala服务端:balabalabalabala服务端:哈哈哈哈哈啊哈哈哈哈服务端:笑死我了哈哈哈哈哈哈哈

就这样,只需要一次http请求,就会有源源不断的信息传送了,是不是很方便。

(2)消耗资源问题

首先,了解一下,我们所用的程序是要经过两层代理的,即http协议在Nginx等服务器的解析下,然后再传送给相应的Handler(PHP等)来处理。简单地说,我们有一个非常快速的接线员(Nginx),他负责把问题转交给相应的客服(Handler) 。

本身接线员基本上速度是足够的,但是每次都卡在客服(Handler)了,老有客服处理速度太慢,导致客服不够。

webSocket就解决了这样一个难题,建立后,可以直接跟接线员建立持久连接,有信息的时候客服想办法通知接线员,然后接线员再统一转交给客户。

这样就可以解决客服处理速度过慢的问题了。

同时,在传统的方式上,要不断的建立,关闭HTTP协议,由于HTTP是非状态性的,每次都要重新传输鉴别信息,来告诉服务端你是谁。

虽然接线员很快速,但是每次都要听这么一堆,效率也会有所下降的,同时还得不断把这些信息转交给客服,不但浪费客服的处理时间,而且还会在网路传输中消耗过多的流量/时间。

但是webSocket只需要一次http握手,所以说整个通讯过程是建立在一次连接/状态中,也就避免了http的非状态性,服务端会一直知道你的信息,直到你关闭请求,这样就解决了接线员要反复解析http协议,还要查看identity info的信息。

六、Socket.io

既然说到了webSocket,就难免扯到socket.io。

有人说socket.io就是对webSocket的封装,并且实现了webSocket的服务端代码。可以这样说,但不完全正确。

在webSocket没有出现之前,实现与服务端的实时通讯可以通过轮询来完成任务。Socket.io将webSocket和轮询(Polling)机制以及其它的实时通信方式封装成了通用的接口,并且在服务端实现了这些实时机制的相应代码。也就是说,webSocket仅仅是Socket.io实现实时通信的一个子集。

下面直接上一个用socket.io做的小小聊天室吧。

(1)首先你得有node,然后安装socket.io。

$ npm install socket.io

(2)服务器端(index.js)

'use strict';
module.exports = require('./lib/express'); var app = require('express')(); var http = require('http').Server(app); var io = require('socket.io')(http); app.get('/', function(req, res){ res.sendFile(__dirname + '/index.html'); }); io.on('connection', function(socket){ socket.on('message',function(msg){ console.log(msg); socket.broadcast.emit('chat',msg); //广播消息 }) }); http.listen(3000);

(3)客户端

先引入js文件:

<script src="/socket.io/socket.io.js"></script>

交互代码(index.html):

<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>聊天室</title> <style> body,div,ul,li{margin: 0;padding: 0;list-style: none;} .auto{margin: auto;} .l{text-align: left;} .r{text-align: right;} .flex{display: box;display: -webkit-box;display: -moz-box;display: -ms-flexbox;display: -webkit-flex;display: flex;-webkit-box-pack: center;-webkit-justify-content: center;-moz-justify-content: center;-ms-justify-content: center;-o-justify-content: center;justify-content: center;-webkit-box-align: center;-webkit-align-items: center;-moz-align-items: center;-ms-align-items: center;-o-align-items: center;align-items: center;} .chat-box{background: #f1f1f1;width: 56vw;padding:2vw;height:36vw;border:1px solid #ccc;margin-top: 2vw;} .chat-li{display:inline-block;margin-top: 5px;background: #5CB85C;border-radius: 5px;padding: 3px 10px;color: #fff;} .other-chat-li{background: #fff;color: #333;} .send-box{width: 60vw;border:1px solid #ccc;justify-content: space-between;border-top: 0;} .send-text{width: 50vw; border: none; padding: 10px;outline:0;} .send{width: 10vw;background: #5cb85c; border: none; padding: 10px;color: #fff;cursor: pointer;} .chat-name{color: #f00;} .other-box,.self-box{width: 50%;height:100%;} </style> </head

转载于:https://www.cnblogs.com/leftJS/p/11041346.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/350279.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

动态规划,背包问题

背包问题模型&#xff0c;背包问题是一类整数规划问题&#xff0c;叙述如下&#xff1a;设有n件物品&#xff0c;并且第i件物品的重量为&#xff0c;其价值为&#xff0c;而背包能承受的总重量是&#xff0c;问应如何选择这些物品&#xff0c;才可以使背包中所装物品的价值最大…

routing zuul_尚学堂0131之zuul的相关概念及如何性能调优

采用服务名称指定路由方式1.1使用服务名称指定路由的规则是什么&#xff1f;1.2需改配置文件&#xff0c;将路由规则修改为使用服务名称路由。通过服务名, service-id为服务名zuul:routes:E-Book-Product-Provider:path: /suibian/**service-id: E-Book-Product-Provider路由的…

实时通信:使用Spring Boot实现Websocket

在开发Web应用程序时&#xff0c;有时我们需要将服务器事件下推到已连接的客户端。 但是&#xff0c;HTTP并非旨在允许这样做。 客户端打开与服务器的连接并请求数据。 服务器不会打开与客户端的连接并推送数据。 为了解决此限制&#xff0c;建立了一种轮询模式&#xff0c;其…

CUDA10.1配置VS2017

目录 一 CUDA 安装 二 CUDA环境变量配置 三 CUDA配置VS2017 一 CUDA 安装 1.1 CUDA下载 网址&#xff1a;https://developer.nvidia.com/cuda-toolkit-archive 可以根据需要下载不同版本的CUDA安装包。 1.2 CUDA安装 1.2.1 双击下载的.exe文件安装 1.2.2 点击‘OK’ 1.2…

鸿蒙应用开发 常用组件与布局

简介 HarmonyOS ArkUI 提供了丰富多样的 UI 组件&#xff0c;您可以使用这些组件轻松地编写出更加丰富、漂亮的界面。在本篇 Codelab 中&#xff0c;您将通过一个简单的购物社交应用示例&#xff0c;学习如何使用常用的基础组件和容器组件。本示例主要包含&#xff1a;“登录”…

[数论]莫比乌斯反演1

索引 莫比乌斯反演1 定理莫比乌斯反演2 证明莫比乌斯反演3 技巧前言 本篇内容全部为定理&#xff0c;无证明 定义 莫比乌斯函数的符号为\(\mu\)&#xff0c;通俗的来讲\[ \mu(n) \left\{ \begin{matrix} 1 & n1\\ (-1)^k & n p_1p_2p_3\dots p_k\\ 0 & \text{其他…

怎么卸载光速头条_我用这三招,整理了桌面并且屏蔽了广告弹窗

这段时间&#xff0c;在用公司电脑工作时&#xff0c;有两个问题让我非常不爽。一是正处在专心工作中&#xff0c;突然桌面中间就弹出一个&#xff1a;天猫双12的广告&#xff0c;而且还没有关闭按钮。只能打开然后再关闭。二是每次打开电脑&#xff0c;桌面中间和右下角就有一…

Qt配置VS2017

目录 一 Qt安装 二 VS2017安装 三 Qt配置VS2017 一 Qt安装 1.1 下载网址&#xff1a;http://download.qt.io/archive/qt/ 这里选择 1.2 安装Qt 安装路径可以自己更改&#xff0c;然后点下一步 可以根据自己的VS版本自己选择&#xff0c;我们这里选MSVC-2017 64-bit 二…

opencv python tutorials_OpenCV-Python Tutorials 笔记(二)

OpenCV官方有一个面向python的文档OpenCV-PythonTutorials&#xff1a;我根据此文档进行了实践学习&#xff0c;结合自己经验简单记录一下笔记。(续)4、Image Processing inOpenCV4.1ChangingColorspaces转换颜色空间算是极其常用的操作了。不用说&#xff0c;cvtColor()。相关…

runltp出现问题 [

runltp 623行&#xff1a; if [ "$?" "0" ]; then 对[解析出了问题。 我灵机一动&#xff0c;是不是sh的问题。 which sh /bin/sh ls -l /bin/sh sh指向dash 果然不对 rm后 ln -s /bin/bash /bin/sh 再次运行&#xff0c;正确。 转载于:https://www.cnbl…

fork join框架_Java 7:Fork / Join框架示例

fork join框架Java 7中的Fork / Join Framework专为可分解为较小任务的工作而设计&#xff0c;并将这些任务的结果组合起来以产生最终结果。 通常&#xff0c;使用Fork / Join Framework的类遵循以下简单算法&#xff1a; // pseudocode Result solve(Problem problem) {if (p…

numpy T、transpose()函数、swapaxes()函数

目录 1 矩阵转置T&#xff0c;既线性代数中矩阵转置 2 transpose()函数 3 swapaxes()函数 1 矩阵转置T&#xff0c;既线性代数中矩阵转置 示例程序如下&#xff1a; import numpy as npa np.arange(0,24,2).reshape(3, 4)print(*****a****) print(a: \n, a) print(a.…

leetcode-54 螺旋矩阵

题目: 给定一个包含 m x n 个元素的矩阵&#xff08;m 行, n 列&#xff09;&#xff0c;请按照顺时针螺旋顺序&#xff0c;返回矩阵中的所有元素。示例 1:输入:[[ 1, 2, 3 ],[ 4, 5, 6 ],[ 7, 8, 9 ]]输出: [1,2,3,6,9,8,7,4,5]示例 2:输入:[ [1, 2, 3, 4], [5, 6, 7, 8], [9,…

米线店结账程序 装饰着模式_实验报告2_装饰者模式

序号&#xff1a;姓名&#xff1a;杨林燕学号&#xff1a;106专业&#xff1a;软件工程日期&#xff1a;成绩&#xff1a;实验二装饰者模式的运用一、实验目的&#xff1a;装饰者模式动态地将责任附加到对象上&#xff0c;若要扩展功能&#xff0c;装饰者提供了比继承更有弹性的…

Java的内置垃圾收集如何使您的生活更美好(大部分时间)

通过从应用程序中学习企业APM产品&#xff0c;发现更快&#xff0c;更高效的性能监控。 参加AppDynamics APM导览&#xff01; “无需为用户编写将寄存器返回到自由存储列表的程序。” 该行&#xff08;以及随后的十几行&#xff09;被埋在约翰麦卡锡&#xff08;John McCart…

PyOpenCV 坐标系统

pyOpenCV中的坐标系统&#xff0c;以图片左上角为原点&#xff08;0,0&#xff09;&#xff0c;水平方向为x轴&#xff08;也既图像的宽度width&#xff09;&#xff0c;竖直方向为y轴&#xff08;也既图像的高度height&#xff09;&#xff0c;如下图所示&#xff1a; #图像中…

office 论文 页码_毕业论文必备技巧:Word页码从第三页开始设置方法

许多应届毕业生在排版毕业论文时候&#xff0c;都会按要求设置页码&#xff0c;第一页是封面&#xff0c;第二页是目录&#xff0c;那么正文内容就要从第三页正式开始了。按照正规设置方式&#xff0c;那么页码此时应该是第三页。但是按照论文格式规定&#xff0c;页码应该是从…

散列

一.什么是散列 散列使用一个散列函数&#xff0c;将一个键映射到一个索引上。散列非常高效。使用散列将耗费O(1)时间来查找、插入、及删除一个元素。 映射表是一种用散列实现的数据结构&#xff0c;映射表是一种存储条目的容器&#xff0c;每个条目包含两个部分&#xff1a;一个…

移动端触摸(touch)事件

目有个交互需要实现手指滑动的交互&#xff0c;pc端使用mousedown,mousemove,mouseup监听实现。 但在ios设备上mousemove是不好监听的&#xff0c;同类的方法是touchstart,touchmove,touchend。 项目需求&#xff0c;需要用到拖动事件。由于不需要考虑IE8等低端浏览器的兼容性&…

numcpp速度对比_PHP和C++性能对比.pdf

PHP 与C性能比较本文博客链接&#xff1a;http://keping.me/php_vs_cpp/PHP 是速度很快的脚本语言&#xff0c;但是用了框架以后好像感觉挺慢的。于是猜测会不会PHP 本身也不是很快。如果不是很快&#xff0c;能否采用 PHP 调用本地动态链接库的形式来提升速度。于是有了下面的…