✊不积跬步,无以至千里;不积小流,无以成江海。
BOM
BOM 在 JavaScript 中指的是浏览器对象模型(Browser Object Model)。BOM 是 JavaScript 对浏览器窗口对象、文档对象和其他浏览器对象的集合。BOM 提供了访问和控制浏览器窗口、文档和其他浏览器对象的 API。
BOM 中的常见对象包括:
- window:代表浏览器窗口。
- document:代表 HTML 文档。
- navigator:代表浏览器。
- screen:代表屏幕。
- location:代表当前 URL。
BOM 可以用于以下操作:
- 控制浏览器窗口的大小、位置和属性。
- 访问和修改 HTML 文档的内容。
- 获取浏览器的信息。
- 获取屏幕的信息。
- 获取当前 URL。
通过了解 BOM,可以实现对浏览器窗口、文档和其他浏览器对象的访问和控制。
以下是使用 BOM 的示例:
// 获取浏览器窗口的大小
const width = window.innerWidth;
const height = window.innerHeight;
// 修改 HTML 文档的内容
document.querySelector('h1').textContent = 'Hello, world!';
// 获取浏览器的信息
const browserName = navigator.userAgent;
// 获取屏幕的信息
const screenWidth = screen.width;
const screenHeight = screen.height;
// 获取当前 URL
const url = location.href;
navigator、history api
navigator 和 History API 是 Web 浏览器提供的两个 JavaScript API,用于获取浏览器和导航历史相关的信息,以及对浏览器历史进行操作。
-
navigator对象:navigator是一个全局对象,提供了有关浏览器环境和用户代理的信息。它包含了一些属性和方法,例如:navigator.userAgent:返回包含用户代理字符串的浏览器标识信息。navigator.platform:返回操作系统平台的信息。navigator.language:返回用户首选的语言设置。navigator.geolocation:提供了访问用户地理位置的方法。
通过 navigator 对象,可以根据浏览器的特性和环境信息,编写适应不同浏览器的代码。
console.log(navigator.userAgent); // 输出浏览器的用户代理字符串
console.log(navigator.platform); // 输出操作系统平台信息
console.log(navigator.language); // 输出用户首选的语言设置
// 输出用户访问用户地理位置的设置
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
function (position) {
console.log("纬度:" + position.coords.latitude);
console.log("经度:" + position.coords.longitude);
},
function (error) {
console.log("无法获取位置信息:" + error.message);
}
);
} else {
console.log("浏览器不支持地理位置定位。");
}
-
History API:History API 允许 JavaScript 动态修改浏览器的历史记录,并对页面进行导航操作,而不需要刷新整个页面。它提供了一组方法和属性,用于管理浏览器历史记录栈,包括:
history.pushState(state, title, url):向浏览器历史记录栈中添加一个新的状态,并且改变当前 URL。history.replaceState(state, title, url):替换当前的历史状态,并且改变当前 URL。history.popState:在历史记录发生变化时触发的事件,可以监听该事件来响应历史记录的变化。
通过 History API,开发者可以在不刷新整个页面的情况下,使用 JavaScript 动态更新 URL 和状态,实现更流畅的用户体验,例如实现单页应用(SPA)或实现前端路由。
需要注意的是,History API 只能在支持 HTML5 的现代浏览器中使用。对于不支持的浏览器,可以使用传统的 URL 锚点(hash)来实现类似的效果。
// 添加新的历史状态并改变当前 URL
history.pushState({ page: "home" }, "Home", "/home");
// 替换当前的历史状态并改变当前 URL
history.replaceState({ page: "about" }, "About", "/about");
// 监听 popstate 事件
window.addEventListener("popstate", function (event) {
console.log("历史记录发生变化");
console.log("当前状态对象:", event.state);
});
上述代码中,在使用 pushState 和 replaceState 方法时,可以提供一个状态对象和相应的标题和 URL。这样做会修改浏览器的历史记录,并且不会导致页面刷新。在监听 popstate 事件时,可以在历史记录发生变化时执行相应的操作。
pushState、repalceState、onpopstate实现单页
要实现单页应用(Single-Page Application,SPA),可以使用 pushState、replaceState 和 popstate 事件来动态更新页面内容,而无需刷新整个页面。下面是一个简单的示例
// 选择页面中的导航链接
const navLinks = document.querySelectorAll("a.nav-link");
// 监听导航链接的点击事件
navLinks.forEach((link) => {
link.addEventListener("click", function (event) {
event.preventDefault(); // 阻止默认的链接行为
const url = this.getAttribute("href"); // 获取链接的目标 URL
const title = this.textContent; // 获取链接的标题
// 添加新的历史状态并改变当前 URL
history.pushState({ url, title }, title, url);
// 加载新页面内容
loadPage(url);
});
});
// 监听 popstate 事件
window.addEventListener("popstate", function (event) {
const state = event.state;
if (state) {
const url = state.url;
const title = state.title;
// 加载历史页面内容
loadPage(url);
}
});
// 加载页面内容
function loadPage(url) {
// 使用 AJAX 或其他方式加载页面内容,例如:
fetch(url)
.then((response) => response.text())
.then((html) => {
// 将页面内容更新到对应的容器中
const pageContainer = document.getElementById("page-container");
pageContainer.innerHTML = html;
})
.catch((error) => {
console.error("页面加载出错:", error);
});
}
在上述示例中,首先选择页面中的导航链接,并通过事件监听捕获导航链接的点击事件。每当点击链接时,阻止默认的链接行为,获取目标 URL 和标题,并使用 pushState 方法添加新的历史状态。然后,调用 loadPage 函数加载新页面内容。
在 popstate 事件监听器中,获取历史状态对象,并从中提取目标 URL 和标题,然后调用 loadPage 函数加载历史页面内容。
在 loadPage 函数中,可以使用 AJAX 或其他方式加载页面内容,并将内容更新到对应的容器中。
上述示例仅展示了一个简单的单页应用的基本思路,实际应用中可能需要更多的处理逻辑,例如路由管理、组件加载、状态管理等。这些可以借助现有的前端框架(如React、Vue、Angular等)或自行实现。
为什么要监听 popstate 事件
监听 popstate 事件是为了处理浏览器历史记录的变化。当用户点击浏览器的前进或后退按钮时,或者通过 JavaScript 调用 history.back() 或 history.forward() 方法时,popstate 事件会被触发。
通过监听 popstate 事件,可以在历史记录发生变化时执行相应的操作,例如加载历史页面内容或执行其他页面更新逻辑。这样可以使单页应用在用户导航时保持同步,并且提供良好的用户体验。
在单页应用中,通过使用 pushState 方法添加新的历史状态,可以使每个页面的 URL 发生变化,但实际上并没有进行页面的刷新或跳转。这意味着用户可以使用浏览器的前进和后退按钮导航不同的页面状态。
通过监听 popstate 事件,可以捕获这些历史记录的变化,并根据历史状态对象中的信息,加载相应的页面内容,以便与当前的 URL 和状态保持一致,从而实现单页应用的效果。
需要注意的是,当使用 pushState 或 replaceState 方法添加或替换历史状态时,不会触发 popstate 事件。因此,在单页应用中,除了在初始加载时监听 popstate 事件外,还需要在导航链接点击时使用 pushState 方法来修改历史状态,以便在历史记录发生变化时触发 popstate 事件。
fetch(url).then((response) => response.text())
fetch(url) 是一个用于发起网络请求的 JavaScript 函数。它接收一个 URL 参数,用于指定要请求的资源的位置。
.then((response) => response.text()) 是对 fetch 函数返回的 Promise 对象进行处理的一部分。Promise 是 JavaScript 中用于处理异步操作的一种机制,它可以在异步操作完成后返回结果或抛出错误。
在这里,.then() 方法用于指定当网络请求成功返回响应时要执行的回调函数。回调函数中的 response 参数表示从服务器返回的响应对象。通过调用 response.text() 方法,我们获取到响应的内容,并返回一个新的 Promise 对象,该对象将在内容获取成功后传递给下一个 .then() 方法。
所以,fetch(url).then((response) => response.text()) 的作用是发起网络请求,并将响应的内容作为文本返回。这样我们可以进一步处理该文本内容,例如将其插入到页面的容器中显示。
localStorage的特点和用法,给localStorage设置过期时间
localStorage 是浏览器提供的一种用于在客户端存储数据的机制。它具有以下特点:
- 持久性:存储在
localStorage中的数据在浏览器关闭后仍然保留,下次打开页面时仍然可用。 - 容量:
localStorage的存储容量通常较大,一般为几兆字节(MB)。 - 域名绑定:
localStorage是与特定域名相关联的,每个域名都有自己独立的localStorage。 - 仅在客户端使用:
localStorage中的数据仅在客户端使用,不会被发送到服务器。
以下是 localStorage 的基本使用方法:
- 存储数据:
localStorage.setItem("key", "value"); // 存储数据
- 获取数据:
const value = localStorage.getItem("key"); // 获取数据
- 删除数据:
localStorage.removeItem("key"); // 删除指定的数据
- 清除所有数据:
localStorage.clear(); // 清空所有的数据
要给 localStorage 设置过期时间,可以使用以下方法:
// 存储数据和过期时间
const data = {
value: "data",
expires: Date.now() + 24 * 60 * 60 * 1000, // 设置过期时间为当前时间加一天
};
localStorage.setItem("key", JSON.stringify(data)); // 存储数据
// 获取数据并检查过期时间
const storedData = localStorage.getItem("key");
if (storedData) {
const parsedData = JSON.parse(storedData);
if (parsedData.expires && Date.now() > parsedData.expires) {
localStorage.removeItem("key"); // 数据已过期,删除数据
} else {
const value = parsedData.value; // 数据未过期,使用数据
}
}
在上述示例中,我们将数据和过期时间一起存储在 localStorage 中。当获取数据时,我们解析存储的数据并检查过期时间。如果数据过期,则删除数据;如果数据未过期,则可以使用数据。这样就实现了给 localStorage 设置过期时间的效果。
由于 localStorage 是在客户端存储的,无法直接设置过期时间。因此,我们需要在存储数据时额外保存过期时间,并在使用数据时进行过期时间的检查。
session storage
sessionStorage 是浏览器提供的一种用于在客户端存储数据的机制,它与 localStorage 类似,但具有以下特点:
- 会话级别:存储在
sessionStorage中的数据仅在当前会话期间有效。当用户关闭浏览器标签页或浏览器窗口时,sessionStorage中的数据将被清除。 - 页面隔离:每个页面都有自己独立的
sessionStorage。不同页面之间的sessionStorage数据不共享。 - 容量:
sessionStorage的存储容量通常较大,一般为几兆字节(MB)。 - 仅在客户端使用:
sessionStorage中的数据仅在客户端使用,不会被发送到服务器。
以下是 sessionStorage 的基本使用方法:
- 存储数据:
sessionStorage.setItem("key", "value"); // 存储数据
- 获取数据:
const value = sessionStorage.getItem("key"); // 获取数据
- 删除数据:
sessionStorage.removeItem("key"); // 删除指定的数据
- 清除所有数据:
sessionStorage.clear(); // 清空所有的数据
与 localStorage 类似,sessionStorage 也是通过键值对的方式来存储数据。可以使用 setItem 方法存储数据,getItem 方法获取数据,removeItem 方法删除指定的数据,clear 方法清空所有数据。
需要注意的是,sessionStorage 中的数据仅在当前会话期间有效。当用户关闭浏览器标签页或浏览器窗口时,sessionStorage 中的数据将被清除。这使得 sessionStorage 特别适合存储会话相关的临时数据,例如用户登录状态、会话信息等。
cookie的特点和用法
Cookie 是一种在客户端存储数据的机制,用于在浏览器和服务器之间传递信息。它具有以下特点:
- 持久性:Cookie 可以设置过期时间,可以在浏览器关闭后仍然保留,下次打开页面时仍然可用。
- 容量限制:每个 Cookie 的存储容量通常限制在几千字节(KB)。
- 域名绑定:Cookie 是与特定域名相关联的,每个域名都有自己独立的 Cookie。
- 跨域限制:Cookie 受同源策略的限制,只能在设置它的域名下进行读取和修改。
以下是 Cookie 的基本用法:
- 存储数据:
document.cookie = "key=value; expires=expiration; path=/";
- 获取数据:
const cookies = document.cookie;
- 删除数据:
document.cookie = "key=; expires=expiration; path=/";
在上述代码中,key 表示 Cookie 的名称,value 表示 Cookie 的值,expires 表示 Cookie 的过期时间,path 表示 Cookie 的路径。
要设置 Cookie 的过期时间,可以使用 expires 属性。可以将其设置为一个未来的日期,或使用 Date 对象来指定具体的过期时间。过期时间的设置方式可以是绝对时间,也可以是相对时间。
例如,将 Cookie 的过期时间设置为一小时后:
const expiration = new Date();
expiration.setTime(expiration.getTime() + (1 * 60 * 60 * 1000)); // 设置为当前时间加上一小时。过期时间是使用毫秒数表示的,所以要*1000
document.cookie = "key=value; expires=" + expiration.toUTCString() + "; path=/";
需要注意的是,获取和设置 Cookie 的值是通过 document.cookie 属性进行的。通过读取 document.cookie,可以获取当前页面的所有 Cookie。注意,document.cookie 返回的是一个字符串,需要进行解析和处理才能获取到具体的 Cookie 值。
Cookie 的使用场景包括但不限于以下几种:
- 身份验证和会话管理:可以使用 Cookie 存储用户的身份验证令牌或会话 ID,以便在用户访问网站时进行身份验证和会话管理。
- 用户首选项:可以使用 Cookie 存储用户的偏好设置,例如语言偏好、主题模式等。
- 跟踪和分析:可以使用 Cookie 跟踪用户的行为和活动,以便进行数据分析和个性化推荐。
需要注意的是,由于 Cookie 存储在客户端,因此可以被用户禁用或删除。此外,Cookie 的存储容量有限,过多的 Cookie 可能会影响性能和用户体验。因此,在使用 Cookie 时需要注意合理控制存储的数据量和敏感性,并遵循相关的隐私政策和法规。
session机制
Session 机制是一种在服务器端存储用户状态信息的机制,用于跟踪用户在网站或应用程序中的会话。它具有以下特点:
-
服务器端存储:Session 数据存储在服务器上,而非客户端。服务器会为每个会话分配一个唯一的标识符(Session ID),客户端只会保存该标识符。
-
会话级别:Session 数据仅在用户与服务器之间的会话期间有效。会话期间通常指用户打开网页或应用程序直到关闭网页或注销的时间段。
-
安全性:Session 数据存储在服务器上,相对于存储在客户端(如 Cookie)的数据,更难以被恶意篡改和窃取。然而,仍需采取适当的安全措施,如使用加密传输和适当的会话管理。
-
状态保持:Session 机制可以用于保持用户的状态信息,如用户登录状态、购物车内容、用户偏好等。这使得可以在不同页面间持续跟踪用户的状态。
以下是 Session 机制的基本用法:
-
创建 Session:当用户访问网站或应用程序时,服务器会为其创建一个唯一的 Session ID,并在服务器端创建相应的 Session 对象。
-
存储数据:服务器可以使用 Session 对象来存储和管理用户的状态信息。可以将用户的登录状态、用户偏好等数据存储在 Session 对象中。
-
Session ID 传递:服务器会将 Session ID 发送给客户端,通常通过 Cookie 或 URL 参数的方式。客户端在后续的请求中会携带该 Session ID。
-
访问 Session 数据:服务器在接收到客户端请求时,通过解析 Session ID,可以识别用户对应的 Session 对象,并从中获取存储的用户状态信息。
-
销毁 Session:当用户关闭网页或注销时,服务器会销毁对应的 Session 对象,从而清除用户的会话数据。
需要注意的是,Session 机制需要服务器端支持,通常通过在服务器上存储 Session 数据的方式实现,如存储在内存、数据库或缓存中。具体实现方式因不同的开发框架和技术而异。
Session 机制的使用场景包括但不限于以下几种:
- 用户认证和授权:可以使用 Session 机制存储用户的登录状态和权限信息,以便在用户访问受限资源时进行验证和授权。
- 购物车和订单管理:可以使用 Session 存储用户的购物车内容和订单信息,以便在用户浏览和提交订单时保持状态。
- 用户会话跟踪:可以使用 Session 机制跟踪用户在网站或应用程序中的活动和行为,以提供个性化的用户体验和功能。
总结
在前端,我们需要使用 JavaScript 来存储和获取 session 数据。在后端,我们需要使用 PHP 或其他服务器端语言来生成 session id 并将其发送给客户端。然后,我们需要使用 HTTP 响应头来将 session id 发送给客户端。客户端在接收到 session id 后,会将其存储在 Cookie 中。在每次请求时,客户端都会将 session id 发送给服务器。服务器端可以根据 session id 来获取 session 数据。
jwt原理
JWT(JSON Web Token)是一种用于在网络应用间传递信息的安全方法。它由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。下面是 JWT 的原理和代码实现示例:
JWT 原理:
- 头部(Header):包含算法和令牌类型等信息。通常是一个 JSON 对象,经过 Base64 编码后作为 JWT 的第一部分。
- 载荷(Payload):包含要传递的数据。通常是一个 JSON 对象,可以包含用户的身份信息、权限等。经过 Base64 编码后作为 JWT 的第二部分。
- 签名(Signature):使用头部指定的算法和密钥对头部、载荷进行签名,以确保数据的完整性和真实性。签名通常由头部、载荷和密钥组成,通过指定的算法生成。
JWT 的生成和验证流程如下:
- 生成 JWT:将头部和载荷分别进行 Base64 编码,然后将它们用点号连接起来形成未签名的 JWT。然后使用指定的算法和密钥对未签名的 JWT 进行签名,生成最终的 JWT。
- 发送 JWT:将生成的 JWT 发送给客户端,通常通过放在 HTTP 请求的头部(Authorization 头)或作为请求参数的方式。
- 验证 JWT:服务器接收到 JWT 后,首先解析 JWT,然后验证签名是否有效。如果签名有效,可以获取到头部和载荷中的数据,进行相应的业务逻辑处理。
下面是一个简单的 JWT 的代码实现示例,使用 Node.js 和 jsonwebtoken 库:
安装依赖: npm install jsonwebtoken
生成 JWT:
const jwt = require('jsonwebtoken');
const payload = {
userId: '123456',
username: 'john.doe'
};
const secretKey = 'your_secret_key';
const options = {
expiresIn: '1h'
};
const token = jwt.sign(payload, secretKey, options);
console.log(token);
验证 JWT:
const jwt = require('jsonwebtoken');
const token = 'your_jwt_token';
const secretKey = 'your_secret_key';
try {
const decoded = jwt.verify(token, secretKey);
console.log(decoded);
} catch (error) {
console.log('Invalid token');
}
在上述代码中,我们使用 jsonwebtoken 库来生成和验证 JWT。在生成 JWT 时,我们提供了一个 payload 对象,表示要传递的数据。然后使用指定的密钥对 JWT 进行签名,并指定了过期时间。在验证 JWT 时,我们提供了要验证的 JWT 和相应的密钥,如果验证通过,将会得到解码后的数据。
需要注意的是,密钥应保密并且安全存储。在实际使用中,可以根据具体需求设置更复杂的头部和载荷,选择适合的算法和过期时间。此外,还可以使用 JWT 的功能来实现身份认证、授权和会话管理等场景。
总结
在前端,我们需要使用 JavaScript 来生成 JWT 令牌。在后端,我们需要使用 HTTP 请求来验证 JWT 令牌。