【问题标题】:How to set Content-Security-Policy for Web Workers to work in Edge / Safari?如何为 Web Worker 设置 Content-Security-Policy 以在 Edge / Safari 中工作?
【发布时间】:2019-07-09 22:09:54
【问题描述】:

在尝试使用 Web Worker 时,我不断收到错误代码:18,来自 Edge 和 Safari 的 SecurityError。然而,工作人员在 Firefox / Chrome 中很好。我正在使用一个内联工作者,我将零依赖数据处理函数传递给它。

我的 CSP 已查看:

add_header Content-Security-Policy "default-src 'self'; worker-src 'self' 'inline' *.example.com";

我可以自己添加其他不错的东西,例如本地样式表和 googleapis.com,但我很好奇如何让 Worker 不引发安全错误

来自worker method的片段

// Create an "inline" worker (1:1 at definition time)
    const worker = new Worker(
        // Use a data URI for the worker's src. It inlines the target function and an RPC handler:
        'data:,$$='+asyncFunction+';onmessage='+(e => {
            /* global $$ */

            // Invoking within then() captures exceptions in the supplied async function as rejections
            Promise.resolve(e.data[1]).then(
                v => $$.apply($$, v)
            ).then(
                // success handler - callback(id, SUCCESS(0), result)
                // if `d` is transferable transfer zero-copy
                d => {
                    postMessage([e.data[0], 0, d], [d].filter(x => (
                        (x instanceof ArrayBuffer) ||
                        (x instanceof MessagePort) ||
                        (x instanceof ImageBitmap)
                    )));
                },
                // error handler - callback(id, ERROR(1), error)
                er => { postMessage([e.data[0], 1, '' + er]); }
            );
        })
    );

Edge 为 worker 抛出此错误:

  [object DOMException]: {code: 18, message: "SecurityError", name: 
    "SecurityError"}
    code: 18
    message: "SecurityError"
    name: "SecurityError"

【问题讨论】:

    标签: javascript web-worker content-security-policy nginx-config


    【解决方案1】:

    我不确定为什么数据 url 会导致安全错误,但您可以使用 URL.createObjectURL 加载工作脚本,该脚本在 Edge 中似乎可以正常工作(我没有在 safari 中对其进行测试)。

    这就是它的样子:

    // Create the worker script as a string
    const script = '$$='+asyncFunction+';onmessage='+(e => {
            /* global $$ */
    
            // Invoking within then() captures exceptions in the supplied async function as rejections
            Promise.resolve(e.data[1]).then(
                v => $$.apply($$, v)
            ).then(
                // success handler - callback(id, SUCCESS(0), result)
                // if `d` is transferable transfer zero-copy
                d => {
                    postMessage([e.data[0], 0, d], [d].filter(x => (
                        (x instanceof ArrayBuffer) ||
                        (x instanceof MessagePort) ||
                        (x instanceof ImageBitmap)
                    )));
                },
                // error handler - callback(id, ERROR(1), error)
                er => { postMessage([e.data[0], 1, '' + er]); }
            );
        });
    
    // Create a local url to load the worker
    const blob = new Blob([script]);
    const workerUrl = URL.createObjectURL(blob);
    const worker = new Worker(workerUrl);
    

    如果您需要任何说明,请告诉我!

    【讨论】:

    • 叮叮叮,优胜者。这是我的疏忽。感谢您指出了这一点。此外,Edge 不支持 ImageBitmap,因此需要出来。
    猜你喜欢
    • 2021-07-09
    • 2018-08-13
    • 2021-05-08
    • 1970-01-01
    • 2023-03-20
    • 2019-02-16
    • 2018-05-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多