欢迎光临
我们一直在努力

HTML5有关Web内容

一、Web存储

使用HTML5可以在本地存储用户的浏览数据。(数据以键值对的方式存在,web网页的数据只允许该网页访问使用)

HTML5 Web提供了两种客户端存储机制:

  • localStorage:永久存储,数据不会过期除非手动删除;
  • sessionStorage:会话存储,数据在页面会话结束时清除。

1、两者区别:

2、共同方法与属性

(1)基本方法

设置数据

获取数据

删除数据

获取键名

(2)属性及其他方法

length属性

遍历所有数据

(3)事件监听

storage事件允许监听存储变化,仅在同源的不同标签页/窗口间触发

注:web storage只能存储字符串,复杂数据需要序列化。

二、Web IndexedDB数据库

是一种浏览器内置的NoSQL数据库,用于在客户端存储大量结构化数据。(该数据库允许通过键值对存储复杂的数据对象并支持事务,索引,版本控制和复杂的查询操作等)。

概念对比:

注:indexedDB不需要预先声明字段的定义,只需要创建对象存储和索引;允许同一个存储中的对象有不同的结构,允许随时添加新字段而无需修改结构。

1、IndexedDB特性

  • 键值对存储:数据以键值对存储在对象存储中(object store);
  • 事务支持:所有数据必须在事务内完成,保证数据一致性与完整性;
  • 异步API:所有操作都是异步的,不会阻塞UI线程,使用事件回调或Promises来处理结果;
  • 版本控制:数据库使用版本号管理数据库架构;

  • 索引:支持数据字段建立索引;
  • 离线支持:数据在断网情况下可以继续访问,适合建立离线Web应用。

2、存储方式

在底层为键值对的基础上增加了索引能力。

索引是额外的查找表

3、IndexedDB语法

  • 打开现有/创建新的数据库

        var request=indexedDB.open("databaseName",version);

  • 创建对象存储(类似表)

        var objectStore=db.createObjectStore("storeName",{keyPath:'id',autoIncrement:              true});

  • 添加数据

        objectStore.add({id:1,name:'zhangsan'});

  • 获取数据(根据键值)

        var request=objectStore.get(1);

  • 更新数据(不存在则插入)

        objectStore.put({id:1,name:'zhangsan'});

  • 删除记录(根据键值)

        objectStore.delete(1);

  • 创建事务(指定事务模式:readonly/readwrite)

        var transaction=db.transaction(['storeName'],readwrite);

  • 创建索引

        objectStore.createIndex('nameIndex','name',{unique:false});

// 打开或创建一个数据库
var request = indexedDB.open('databaseName', version);

// 处理数据库升级
request.onupgradeneeded = function(event) {
var db = event.target.result;

// 创建对象存储(表)并设置主键
var objectStore = db.createObjectStore('storeName', { keyPath: 'id' });

// 创建索引
objectStore.createIndex('fieldName', 'fieldName', { unique: false });
};

// 数据库打开成功时的回调
request.onsuccess = function(event) {
var db = event.target.result;

// 进行事务操作
var transaction = db.transaction('storeName', 'readwrite');
var objectStore = transaction.objectStore('storeName');

// 插入数据
objectStore.add({ id: 1, name: 'John Doe', age: 30 });

// 查询数据
var query = objectStore.get(1);
query.onsuccess = function(event) {
console.log(event.target.result);
};
};

// 错误处理
request.onerror = function(event) {
console.error('Database error:', event.target.error);
};

三、Web Workers

web worker是运行在后台的JavaScript,不会影响页面的性能。当html页面执行脚本时,页面的状态是不可响应的,直到脚本完成。但有了web worker(独立于其他脚本)你可以点击或选取页面的内容,而web worker会在后台运行计算处理图像等。(体现了单线程到多线程的扩展)。

1、工作流程(简易版)

生命周期流程

  • 创建阶段:主线程调用new Worker("worker.js")创建worker实例(也就是浏览器先会创建一个全新的JavaScript运行环境也叫线程,后加载指定的js文件)。创建过程中主线程不会被阻塞,可以继续执行后续代码。
  • 初始化阶段:worker线程拥有自己的全局对象self而不是window。并且在该阶段执行全局代码,可以设置事件监听器或者定义函数;
  • 通信准备阶段:主线程通过worker.postMessage(data)向worker传递序列化后的数据,worker通过self.onmessage或addEventListener('message')接收消息;
  • 任务处理阶段:接收到消息后触发message事件,worker在后台处理数据可执行复杂计算,数据处理,图像处理等。
  • 结果返回阶段:通过self.postMessage(result)将结果经过序列化后发送给主线程,主线程通过worker.onmessage接收;
  • 终止阶段:主线程调用worker.terminate()(立即终止,worker无法进行任何清理操作);worker内部调用self.close()worker完成当前任务后关闭。

消息传递流程

调用postMessage———>数据序列化———–>消息入队———->事件循环处理(从消息队列中取)————>触发事件———–>数据反序列化

2、worker的方法

(1)构造函数方法

// 1. 创建基本 Worker
const worker1 = new Worker('worker.js');

// 2. 创建带选项的 Worker
const worker2 = new Worker('worker.js', {
name: 'dataProcessor', // Worker 名称,可在 worker 内通过 self.name 访问
type: 'module', // 作为 ES6 模块加载
credentials: 'include' // 包含跨域请求的凭据
});

// 3. 创建内联 Worker
const workerCode = `
self.onmessage = function(e) {
self.postMessage('Hello from inline worker!');
};
`;

const blob = new Blob([workerCode], { type: 'text/javascript' });
const worker3 = new Worker(URL.createObjectURL(blob));

(2)实例方法

// postMessage(): 向 Worker 发送消息
worker.postMessage('简单字符串');
worker.postMessage({ type: 'data', value: 123 });
worker.postMessage(arrayBuffer, [arrayBuffer]); // 转移所有权

// terminate(): 立即终止 Worker
worker.terminate();
// 注意:terminate() 是同步的,立即生效
// Worker 无法清理资源,无法发送最后的消息

// addEventListener() / removeEventListener(): 事件监听
worker.addEventListener('message', handleMessage);
worker.addEventListener('error', handleError);
worker.removeEventListener('message', handleMessage);

(3)workerglobalscope方法(worker内部方法)

// 1. 消息相关方法
self.postMessage(data); // 发送消息
self.close(); // 关闭 Worker(异步)

// 2. 网络相关方法
fetch('https://api.example.com/data') // 发起网络请求
.then(response => response.json());

// 3. 定时器方法
const timerId = setTimeout(() => {}, 1000);
clearTimeout(timerId);

const intervalId = setInterval(() => {}, 1000);
clearInterval(intervalId);

// 4. 导入脚本
importScripts('helper.js', 'utils.js'); // 同步加载并执行脚本
// 注意:importScripts() 会阻塞直到脚本加载完成

// 5. Worker 作为模块(type: 'module')
// worker.js (作为模块)
import { complexCalculation } from './math.js';
export default function process() { /* … */ }

3、worker属性

(1)实例属性

// 1. onmessage: 消息事件处理器
worker.onmessage = function(event) {
console.log('收到消息:', event.data);
console.log('来源:', event.source); // 通常是 worker 自身
console.log('端口:', event.ports); // MessageChannel 的端口
};

// 2. onerror: 错误事件处理器
worker.onerror = function(event) {
console.error('错误发生在:', event.filename);
console.error('行号:', event.lineno);
console.error('列号:', event.colno);
console.error('错误信息:', event.message);
};

// 3. onmessageerror: 消息传递错误处理器
worker.onmessageerror = function(event) {
console.error('无法反序列化消息');
};

(2)workerglobalscope属性

// 1. 自身引用
self; // WorkerGlobalScope 实例
this; // 同 self
globalThis; // ES2020 标准,同 self

// 2. 名称和标识
self.name; // Worker 名称(构造函数选项中设置)
self.location; // Worker 脚本的 URL 信息

// 3. 浏览器环境
self.navigator; // 浏览器信息(有限)
self.console; // 控制台对象
self.caches; // CacheStorage 对象(Service Worker 相关)
self.indexedDB; // IndexedDB 接口

// 4. 性能相关
self.performance; // Performance 对象(时间测量)

注意:使用worker的主要限制

  • worker脚本必须与主脚本同源;
  • 无法直接访问DOM;
  • 没有window,document对象;
  • 不允许使用XMLhTTPequest同步模式。

四、SSE(服务器发送事件)

是一种允许服务器向客户端单向推送数据的技术(或者说是网页自动获取来自服务器的更新),基于HTTP协议。

1、主要作用

  • 实时数据推送
  • 服务器状态监控
  • 实时消息通知
  • 数据流传输
  • 长轮询替代方案

2、工作原理

  • 建立连接:客户端通过JavaScript的EventSource API向服务器发起一个普通http请求建立连接并保持该链接处于打开状态;
  • 保持连接:服务器与客户端保持这个连接,客户端等待接收数据;
  • 数据传输:数据格式为每条消息以文本形式发送,每条消息以\\n\\n为结束标志,服务器随时可以发消息,不需要等客户端请求;
  • 客户端处理:浏览器自动解析SSE格式消息。如有event字段触发对应的事件监听器,若无则触发默认的onmessage事件;
  • 断线重连:客户端会自动尝试重新连接,重连后,客户端会发送上次收到的最后一个消息ID。

3、消息格式

设置内容类型为:text/event-stream

data:消息内容

event:事件类型

id:事件id

retry:重连时间

空白行:消息分隔行

4、客户端API详解

(1)EventSource构造函数

(2)EventSource属性

const es = new EventSource('/stream');

// 只读属性
console.log(es.url); // 服务器端点的URL
console.log(es.readyState); // 连接状态:
// 0: CONNECTING (连接中)
// 1: OPEN (已连接)
// 2: CLOSED (已关闭)

// 事件处理器(可读写)
es.onopen = function(event) {
console.log('连接已建立');
};

es.onmessage = function(event) {
console.log('收到消息:', event.data);
console.log('最后事件ID:', event.lastEventId);
};

es.onerror = function(event) {
console.log('连接错误:', event);
if (es.readyState === EventSource.CONNECTING) {
console.log('正在重新连接…');
} else if (es.readyState === EventSource.CLOSED) {
console.log('连接已关闭');
}
};

(3)EventSource方法

const es = new EventSource('/events');

// 关闭连接
es.close();

// 示例:带超时和重试的智能连接管理
class SmartEventSource {
constructor(url, options = {}) {
this.url = url;
this.maxRetries = options.maxRetries || 5;
this.retryCount = 0;
this.reconnectDelay = options.reconnectDelay || 3000;
this.timeout = options.timeout || 30000;
this.connect();
}

connect() {
this.es = new EventSource(this.url);
this.setupEventHandlers();
this.startTimeoutTimer();
}

setupEventHandlers() {
this.es.onopen = () => {
console.log('SSE连接成功');
this.retryCount = 0; // 重置重试计数
this.clearTimeoutTimer();
};

this.es.onerror = (event) => {
console.error('SSE连接错误');
this.clearTimeoutTimer();

if (this.retryCount < this.maxRetries) {
this.retryCount++;
const delay = this.reconnectDelay * Math.pow(2, this.retryCount);
console.log(`${delay}ms后重试 (${this.retryCount}/${this.maxRetries})`);

setTimeout(() => {
if (this.es.readyState === EventSource.CLOSED) {
this.connect();
}
}, delay);
}
};
}

startTimeoutTimer() {
this.timeoutTimer = setTimeout(() => {
console.warn('连接超时,重新连接');
this.es.close();
this.connect();
}, this.timeout);
}

clearTimeoutTimer() {
if (this.timeoutTimer) {
clearTimeout(this.timeoutTimer);
}
}
}

赞(0)
未经允许不得转载:171主机测评 » HTML5有关Web内容
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址