Service Workers

ServiceWorkers是浏览器中的代理层,能拦截并修改网络请求。本文详细介绍了如何使用ServiceWorkers来处理对特定资源服务器的请求,添加访问令牌,并在接收到无效_token错误时自动重试请求,同时更新访问令牌。
摘要由CSDN通过智能技术生成

Service Workers

前言

Service Workers 是浏览器平台中的一个相对较新的功能。它们的核心是提供一个单独的JavaScript执行上下文,该上下文可以拦截(并可能修改)主要执行上下文生成的所有网络流量。本质上,它们是浏览器中存在的代理层,位于主应用程序代码与其调用的网络端点之间。

使用详解

// This is how service workers intercept network request events -
// every network request made by the application code will trigger
// this event listener.
// 这就是服务工作人员拦截网络请求事件的方式——应用程序代码发出的每个网络请求都将触发这个事件侦听器。
self.addEventListener("fetch", (event) => {

	// By the time this event listener is called, the service worker should
	// already have been configured to watch for requests to particular servers.
	// 在调用此事件侦听器时,服务工作人员应该已经配置为监视对特定服务器的请求。
	if (self.appAuthConfig &&
		typeof self.appAuthConfig.resourceServers === "object" &&
		Object.keys(self.appAuthConfig.resourceServers).length) {

		// Check to see if this particular network request event
		// is to one of the configured resource servers.
		// 检查此特定网络请求事件是否指向已配置的资源服务器之一。
		var resourceServer = Object.keys(self.appAuthConfig.resourceServers)
			.filter((rs) => event.request.url.indexOf(rs) === 0)[0];

		if (resourceServer) {
			// This is how service workers alter the response that is
			// presented to the application code - You can resolve the
			// promise passed into `respondWith` with any Response object.
			// 这就是服务工作人员更改呈现给应用程序代码的响应的方式——您可以用任何响应对象解析传递到‘respondWith’的承诺。
			// https://developer.mozilla.org/en-US/docs/Web/API/Response
			event.respondWith(new Promise((resolve, reject) => {

				// Modify the current request by adding the appropriate
				// access token to it.
				// 通过添加适当的访问令牌来修改当前请求。
				self.addAccessTokenToRequest(event.request, resourceServer)
					// Make the token-bearing request to the resource server.
					// 向资源服务器发出带有令牌的请求。
					.then((rsRequest) => fetch(rsRequest))
					.then((resp) => {
						// Check for the special-case error that we can possibly recover from.
						// 检查特殊情况的错误,我们可以恢复。
						if (!resp.ok && getAuthHeaderDetails(resp.headers)["error"] === "invalid_token") {
							/*
							From https://tools.ietf.org/html/rfc6750#section-3.1:
							invalid_token
									 The access token provided is expired, revoked, malformed, or
									 invalid for other reasons.  The resource SHOULD respond with
									 the HTTP 401 (Unauthorized) status code.  The client MAY
									 request a new access token and retry the protected resource
									 request.
									 提供的访问令牌已过期、撤消、格式错误或因其他原因无效。资源应该使用HTTP 401(未授权)状态码响应。客户端可以请求新的访问令牌并重试受保护的资源请求。

							We are going to follow the advice of the RFC here and try to request a new
							access token and retry the request.
							我们将遵循RFC的建议,尝试请求一个新的访问令牌,然后重试该请求。
							*/
							let promise = self.waitForRenewedToken(resourceServer)
								.then(() => self.addAccessTokenToRequest(event.request, resourceServer))
								.then((freshRSRequest) => fetch(freshRSRequest));

							// The act of obtaining a fresh token is done outside
							// of the service worker. Use a MessageChannel to signal
							// the main execution context that a fresh token is needed.
							// 获取新令牌的操作是在服务工作人员之外完成的。使用消息机制向主执行上下文发出需要新标记的信号。
							// https://developer.mozilla.org/en-US/docs/Web/API/MessageChannel
							self.messageChannel.postMessage({
								"message": "renewTokens",
								"resourceServer": resourceServer
							});
							return promise;
						} else {
							return resp;
						}
					})
					.then(resolve, reject);
			}));
		}
	}
	return;
});

参考文章

使用Service Worker为您的JS应用构建身份代理

使用 Service Workers

ServiceWorker详解

案例

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值