SharedArrayBuffer is not defined

Uncaught ReferenceError: SharedArrayBuffer is not defined


这个错误通常是因为浏览器的安全策略限制导致的。


SharedArrayBuffer 错误原因

SharedArrayBuffer 需要特殊的浏览器安全设置才能使用,主要是因为安全漏洞(如 Spectre 攻击)的原因,现代浏览器默认禁用了它。


跨源隔离(Cross-Origin Isolation)

要在浏览器中使用 SharedArrayBuffer,必须启用跨源隔离。这需要在服务器响应头中设置以下两个头部:

Cross-Origin-Embedder-Policy: require-corp

Cross-Origin-Opener-Policy: same-origin


或更宽松的配置

Cross-Origin-Opener-Policy: same-origin

Cross-Origin-Embedder-Policy: same-origin


使用本地服务器而非文件协议

不要直接双击 HTML 文件打开(file:// 协议),而是使用本地服务器。


本地开发时的快速解决方案

第一步:Chrome 浏览器 禁用 Web 安全

启动 Chrome 时添加以下标志:

bash

bash 复制代码
chrome --disable-web-security --user-data-dir=/tmp/chrome-test

Windows系统上启动 Chrome 并添加标志的方法:

方法1:使用 CMD 命令行(最简单)
  1. Win + R,输入 cmd,回车

  2. 在 CMD 中输入:


cmd

复制代码
"C:\Program Files\Google\Chrome\Application\chrome.exe" --disable-web-security --user-data-dir="C:\temp\chrome-test"

方法2:在 PowerShell 中正确的语法

powershell

复制代码
& "C:\Program Files\Google\Chrome\Application\chrome.exe" "--disable-web-security" "--user-data-dir=C:\temp\chrome-test"

或者:

powershell

复制代码
Start-Process "C:\Program Files\Google\Chrome\Application\chrome.exe" -ArgumentList "--disable-web-security", "--user-data-dir=C:\temp\chrome-test"

验证是否成功

启动后,你应该看到 Chrome 顶部的警告横幅:

text

复制代码
您使用的是不受支持的命令行标记:--disable-web-security。稳定性和安全性会有所下降。


后续页面打开都在这个新弹出的窗口中进行测试


其他方式:创建快捷方式

  1. 右键点击 Chrome 快捷方式,选择"属性"

  2. 在"目标"字段的末尾添加:

    复制代码
    --disable-web-security --user-data-dir="C:\temp\chrome-test"
  3. 完整的目标路径应该类似:

    复制代码
    "C:\Program Files\Google\Chrome\Application\chrome.exe" --disable-web-security --user-data-dir="C:\temp\chrome-test"
  4. 点击"应用",然后双击此快捷方式启动


或者使用 Chrome 扩展程序(推荐,但可能无法获取)

安装这些扩展可以绕过 CORS 限制:

  1. Allow CORS: Access-Control-Allow-Origin

    • Chrome Web Store 链接:https://chrome.google.com/webstore/detail/allow-cors-access-control/lhobafahddgcelffkeicbaginigeejlf

    • 安装后,点击图标开启/关闭

  2. Moesif CORS

    • 功能更强大,可以自定义配置

    • 链接:https://chrome.google.com/webstore/detail/moesif-origin-cors-change/digfbfaphojjndkpccljibejjbppifbc


HTTPS要求

请注意,大多数浏览器要求使用HTTPS才能启用SharedArrayBuffer(localhost除外)。


即使禁用了 Web 安全,SharedArrayBuffer 仍然需要特定的 HTTP 头部才能启用。

浏览器的警告横幅只是禁用了 CORS,但没有设置必要的 COOP/COEP 头部。


第二步:必须设置正确的响应头(使用本地服务器并设置头部)

1、使用 Node.js + Express

javascript

javascript 复制代码
// server.js
const express = require('express');
const app = express();
const path = require('path');

// 设置必需的头部
app.use((req, res, next) => {
    res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
    res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
    res.setHeader('Access-Control-Allow-Origin', '*');
    next();
});

app.use(express.static('.'));

app.listen(8080, () => {
    console.log('Server running at http://localhost:8080/');
    console.log('Headers set: COOP=same-origin, COEP=require-corp');
});

运行:

bash

复制代码
node server.js

安装 Express

bash 复制代码
# 临时使用淘宝镜像安装
npm install -g express --registry=https://registry.npmmirror.com

# 或者设置永久使用淘宝镜像
npm config set registry https://registry.npmmirror.com

# 验证配置
npm config get registry

2、使用纯 Node.js(无需额外安装 Express)

创建 server.js

javascript

javascript 复制代码
const http = require('http');
const fs = require('fs');
const path = require('path');

const server = http.createServer((req, res) => {
    console.log(`${req.method} ${req.url}`);
    
    // 设置必需的头部
    res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
    res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
    res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
    
    // 处理 OPTIONS 预检请求
    if (req.method === 'OPTIONS') {
        res.writeHead(200);
        res.end();
        return;
    }
    
    // 确定请求的文件路径
    let filePath = '.' + req.url;
    if (filePath === './') {
        filePath = './worker.html'; // 默认加载你的 HTML 文件
    }
    
    // 获取文件扩展名
    const extname = path.extname(filePath);
    let contentType = 'text/html';
    
    // 根据扩展名设置 Content-Type
    switch (extname) {
        case '.js':
            contentType = 'text/javascript';
            break;
        case '.css':
            contentType = 'text/css';
            break;
        case '.json':
            contentType = 'application/json';
            break;
        case '.png':
            contentType = 'image/png';
            break;
        case '.jpg':
            contentType = 'image/jpg';
            break;
        case '.wasm':
            contentType = 'application/wasm';
            break;
    }
    
    // 读取文件
    fs.readFile(filePath, (error, content) => {
        if (error) {
            if (error.code === 'ENOENT') {
                // 文件不存在
                fs.readFile('./404.html', (err, notFoundContent) => {
                    if (err) {
                        res.writeHead(404, { 'Content-Type': 'text/plain' });
                        res.end('404 Not Found\n');
                    } else {
                        res.writeHead(404, { 'Content-Type': 'text/html' });
                        res.end(notFoundContent, 'utf-8');
                    }
                });
            } else {
                // 服务器错误
                res.writeHead(500);
                res.end('Server Error: ' + error.code);
            }
        } else {
            // 成功响应
            res.writeHead(200, { 
                'Content-Type': contentType,
                'Content-Length': content.length
            });
            res.end(content, 'utf-8');
        }
    });
});

const port = 8080;
server.listen(port, () => {
    console.log(`Server running at http://localhost:${port}`);
    console.log('Required headers are set:');
    console.log('  Cross-Origin-Opener-Policy: same-origin');
    console.log('  Cross-Origin-Embedder-Policy: require-corp');
    console.log('  Access-Control-Allow-Origin: *');
    console.log('\nOpen your browser to: http://localhost:8080/worker.html');
});

3、使用 Python(最简单,无需网络)

如果你安装了 Python3(WSL Ubuntu 通常自带):

bash

bash 复制代码
#!/usr/bin/env python3
"""
SharedArrayBuffer 专用服务器
确保设置正确的响应头
"""

import http.server
import socketserver
import os
import sys

def main(port=8000):
    """启动带正确头部的服务器"""
    
    class SABHandler(http.server.SimpleHTTPRequestHandler):
        """SharedArrayBuffer 专用处理器"""
        
        def end_headers(self):
            # 必须的三个头部
            self.send_header('Cross-Origin-Opener-Policy', 'same-origin')
            self.send_header('Cross-Origin-Embedder-Policy', 'require-corp')
            self.send_header('Access-Control-Allow-Origin', '*')
            super().end_headers()
        
        def log_message(self, format, *args):
            # 简化日志,只显示重要请求
            path = self.path
            if path.endswith('.html') or path == '/' or 'worker' in path:
                print(f'📦 {path}')
    
    # 确保在当前目录
    script_dir = os.path.dirname(os.path.abspath(__file__))
    os.chdir(script_dir)
    
    print('\n' + '='*60)
    print('🎯 SHAREDARRAYBUFFER 开发服务器')
    print('='*60)
    print(f'📡 服务器地址: http://localhost:{port}')
    print(f'📁 服务目录: {os.getcwd()}')
    print('\n🔧 已配置的响应头:')
    print('   ✓ Cross-Origin-Opener-Policy: same-origin')
    print('   ✓ Cross-Origin-Embedder-Policy: require-corp')
    print('   ✓ Access-Control-Allow-Origin: *')
    
    # 列出HTML文件
    html_files = [f for f in os.listdir('.') if f.lower().endswith('.html')]
    if html_files:
        print('\n📄 可访问的页面:')
        for html in sorted(html_files):
            print(f'   → http://localhost:{port}/{html}')
    
    print('\n💡 使用说明:')
    print('   1. 访问上面的任一链接')
    print('   2. 按 F12 查看 Network → Headers 确认头部')
    print('   3. SharedArrayBuffer 现在应该可用了')
    print('   4. 按 Ctrl+C 停止服务器')
    print('='*60 + '\n')
    
    try:
        with socketserver.TCPServer(("", port), SABHandler) as httpd:
            httpd.serve_forever()
    except OSError as e:
        if 'Address already in use' in str(e):
            print(f'❌ 端口 {port} 已被占用!')
            print(f'   请使用其他端口: python3 server.py 8080')
            return 1
        raise
    except KeyboardInterrupt:
        print('\n👋 服务器已停止')
        return 0

if __name__ == '__main__':
    # 使用命令行参数指定端口,或默认8000
    port = int(sys.argv[1]) if len(sys.argv) > 1 else 8000
    sys.exit(main(port))

验证是否成功

访问页面,按 F12 打开开发者工具,查看:

  1. Network 标签 → 点击你的文件 → 查看 Response Headers

  2. 应该能看到:

    • Cross-Origin-Opener-Policy: same-origin

    • Cross-Origin-Embedder-Policy: require-corp



建议方案

使用 Python 方案最简单,因为:

  1. WSL Ubuntu 自带 Python3

  2. 无需安装任何额外包

  3. 自动设置所需头部

项目根目录直接运行:

bash 复制代码
python3 server.py

彻底清理所有端口占用


复制代码
Press Ctrl+C to stop the server

在终端中项目根目录运行以下清理命令:


注意:可能需要输入密码


bash 复制代码
# 强力清理所有可能的端口占用
echo "🧹 清理所有可能冲突的进程..."
sudo pkill -f "python.*http.server" 2>/dev/null || true
sudo pkill -f "node.*server" 2>/dev/null || true
sudo pkill -f "http-server" 2>/dev/null || true

# 释放所有相关端口
for port in 3000 3001 3002 8000 8001 8002 8080 8081 8082 8888 5000; do
    sudo fuser -k ${port}/tcp 2>/dev/null || true
done

echo "✅ 清理完成"

检测支持

在使用 SharedArrayBuffer 之前,最好先检测浏览器是否支持:

javascript 复制代码
// 检查 SharedArrayBuffer 是否可用
if (typeof SharedArrayBuffer === 'undefined') {
    // 降级方案:使用普通 ArrayBuffer
    console.warn('SharedArrayBuffer is not available. Using fallback.');
    
    // 创建一个简单的模拟(功能有限)
    window.SharedArrayBuffer = ArrayBuffer;
    
    // 或者根据你的需求调整代码逻辑
    // 例如:使用 worker.postMessage 替代共享内存
}

完整示例

下面是一个使用 SharedArrayBuffer 的完整示例(需要适当的安全头部):

javascript 复制代码
// 在代码中检测支持情况
function isSharedArrayBufferSupported() {
    try {
        if (typeof SharedArrayBuffer !== 'function') {
            return false;
        }
        
        // 测试是否可以实际创建
        const sab = new SharedArrayBuffer(1);
        return sab instanceof SharedArrayBuffer;
    } catch (e) {
        return false;
    }
}

if (!isSharedArrayBufferSupported()) {
    // 提供降级方案或错误提示
    console.error('SharedArrayBuffer is not supported in this environment');
    // 提示用户更新浏览器或使用支持的浏览器
}
相关推荐
Benny的老巢17 天前
Wrangler CLI 工具完整使用指南
cloudflare·workers·wrangler·cloudflare cli·cloudflare 部署
Benny的老巢23 天前
Cloudflare Workers 实现 Resend 邮件发送接口
cloudflare·邮件服务·workers·resend服务
Benny的老巢24 天前
Cloudflare Workers 接口服务能力详解
cloudflare·服务端·workers·接口服务·d1数据库
Benny的老巢24 天前
Cloudflare Workers CORS 跨域问题排查与解决
跨域·cloudflare·cors·workers
QC七哥3 个月前
使用wrangler发布cf的workers项目
workers·站点部署·wrangler
武穆逸仙2 年前
基于Cloudflare/CloudDNS/GitHub使用免费域名部署NewBing的AI服务
人工智能·cloudflare·bingai·workers