1

我已经开始为我的网站使用工作人员。我网站上的工作人员的目的:主要是在 HTML 页面的不同位置注入一些代码(html/js/css)。它可以是一些配置数据,也可以是一些法律文本等。

所以我现在要做的是在 KV 中为每个网站创建一个配置,并基于用户国家/语言注入 html/js 等。

下面是一个存储类(单例模式),它包含来自配置的所有信息,但在工作人员中不起作用,我的意思是,在第一次请求之后,数据是持久的,并且在一段时间后它会更新:

例如第一个请求 URL:/about 第二个请求 URL:/es/about/

按输出console.log(event.request)将显示/es/about,但Store.request输出:/about/

任何解决方法,强制刷新数据,我想因为我不在构造函数中这样做,但是通过调用自定义方法应该可以解决问题,但是它没有。?

下面是一些代码示例。


import { Store } from "@helpers/store";

addEventListener('fetch', event => {
    event.respondWith(handleRequest(event.request))
});

//HTML Rewriter Class
class Head {

    element(el) {
        el.append(`
                <script id="config">
                    var config = ${Store.export()};
                </script>`, {
            html: true
        });
    }
}

async function handleRequest(request) {
    let store = await Store.make(request);

    const response = await fetch(request);

    let html = new HTMLRewriter();
    html.on("head", new Head());

    return html.transform(response);
}

//src/helpers/store.js

class Store {

    constructor(){

        this._request = null
        this._config = {}
        this._url = null

    }

    async make(request){

        let config = {}

        this._request = request;

        const domain = this.url.hostname.replace(/www\./g, "");

        const country = request.headers.get('cf-ipcountry')

        const website = await WEBSITES.get(domain, "json"); //WEBSITES is KV namespace

        const { license, lang } = website;

        this._config = {
            country,
            domain,
            license,
            lang
        };

        return this;
    }

    export(){

        return JSON.stringify(this._config)
    }

    get request(){
        
        return this._request;

    }

    get url(){
        
        if(!this._url){

            this._url = new URL(this.request.url)

        }

        return this._url;

    }
}

export default new Store()
4

2 回答 2

1

您的 Worker 的单个实例可以处理多个请求,包括并发请求。在您的代码中,您使用单例实例Store来存储有关当前请求的元数据。但是如果同时处理多个请求,那么第二个请求将覆盖Store第一个请求完成之前的内容。这可能会导致第一个请求使用来自第二个请求的元数据呈现其 HTML。

似乎使用单例模式不是您想要的。根据代码,您似乎真的想Store为每个请求创建一个单独的实例。

于 2020-10-13T14:47:07.843 回答
0

想到2个问题:

  • 您正在为对工作人员的每次调用创建一个新的 HTMLRewriter。这将导致一些并发问题。重写器的实例化应该在 handleRequst 方法之外完成。例如在导入语句之后。
  • 您正在导入 Store 类并且从不实例化它,而是使用它的方法,就像它们是静态的(它们不是)。这也会给您带来并发问题。
于 2020-12-17T08:53:09.697 回答