Jest安全错误:localStorage在不透明来源中不可用

171
当我想要用命令npm run test来运行我的项目时,我遇到了下面的错误。这是什么原因造成的?
FAIL
● Test suite failed to run

SecurityError: localStorage is not available for opaque origins at Window.get localStorage [as localStorage] (node_modules/jsdom/lib/jsdom/browser/Window.js:257:15)
      at Array.forEach (<anonymous>)

这是测试运行器的问题,@DavidR有问题,无法运行>>>npm run test<<<。 - Martin Chaov
@MartinChaov 是的,我知道。我想看看他的回复,以便检查他的jest配置是否有问题 :-) - David R
1
我刚开始遇到这个问题......我的代码中根本没有使用本地存储。你的代码也使用了ts-jest吗? - k2snowman69
1
为了解释这个错误,我在尝试将jest版本从^22.3.0更新到^23.5.0以及Babel 7时开始看到它。 - Bert
升级 Jest 从 27.5.129.5.0 时遇到相同的问题。 - Daniel Klimuntowski
显示剩余4条评论
14个回答

163

如果你正在使用以 http://localhost 前缀访问应用程序,则需要更新你的 jest 配置(在你的 jest.config.js 文件中)如下:

```json { "testURL": "http://localhost" } ```
  "jest": {
    "verbose": true,
    "testURL": "http://localhost/"
  }

如果您还没有jest配置,只需将配置包含在package.json中即可。例如:

{
  "name": "...",
  "description": "...",
  ...
  "jest": {
    "verbose": true,
    "testURL": "http://localhost/"
  }
}

或者在 jest.config.js 中:

module.exports = {
  verbose: true,
  testURL: "http://localhost/",
  ...
}

或者如果您已经配置了projects

module.exports = {
  verbose: true,
  
  projects: [{
    runner: 'jest-runner',
    testURL: "http://localhost/",

    // ...
  }]
}

对于package.json中的配置,在jest v28中已经删除了testURL。现在,您应该使用testEnvironmentOptions来传递url选项,如下所示:

"jest": {
    "verbose": true,
    "testEnvironmentOptions": {
        "url": "http://localhost/"
    }
}

20
没问题,这对我有效...虽然我不太明白为什么我需要这个,也不知道为什么在最新的升级之前它能工作。 - k2snowman69
1
这个问题在 jest 的 Github 页面上有讨论:https://github.com/facebook/jest/issues/6766 - Jordan Bonitatis
3
你也可以在npm脚本中使用cli选项:jest --testURL=\"http://localhost\"。如果由于其他环境(例如react-scripts)而无法设置全局jest配置,则非常有用。 - Burrich
我正在使用 React Native 进行开发。即使对于我来说,“testUrl”也可以工作。 - Jimit Patel

83

我刚刚在一个大型的单体库中遇到了这个问题(在单元测试中,否则不需要jsdom)。在我们的jest.config.js中(或者是相当于package.json的配置文件)明确设置以下内容也可以缓解这个问题:

module.exports = {
  testEnvironment: 'node'
}

更新:正如 Nicolas 在下面提到的(谢谢!),如果您没有使用任何配置文件,您还可以添加以下标志:

jest --testEnvironment node    
# or 
jest --env=node

3
这对我很有效!这就是你需要的答案!谢谢! - blueprintchris
似乎作者没有一个Node环境 - 在他的情况下,他应该设置testEnvironment:“jsdom”。这对我来说在最新的更新中有效。感谢您的建议! - Philipp Möhler
3
如下其他答案提到的那样,您可以通过运行 jest --testEnvironment node 或其简写形式 jest --env=node 来跳过生成配置文件(或package.json属性)。 - Nicolás Fantone
2
这应该是被接受的答案。对于这个错误来说,它似乎更加合适。此外,如果您只是在测试脚本,定义testURL就没有任何意义。 - Dez

21

你必须指定你将使用哪个环境(--env)。

当你在 package.json 中运行 jest 命令时,你应该指定环境(jsdomnode)。例如:

  "scripts": {
    "jest": "jest --env=node --colors --coverage test",
    "test": "npm run jest"
  },

这应该适合你的需要!


1
如果您正在使用jsdom,无论您是否通过配置或命令行指定了env,都会发生相同的情况。这只是在今天jest的最新更新中才开始发生。如果您遇到此问题,请参阅@David R的答案以获取解决方案。 - fisch2
有道理,环境决定了测试应该如何运行,而jsdom似乎是默认选项。 - Jotham Ardel

11

如果您正在使用jsdom,请确保包含url。

查看jsdom存储库的简单选项。 https://github.com/jsdom/jsdom#simple-options

const jsdom = require("jsdom");
const { JSDOM } = jsdom;

const dom = new JSDOM(`...`, { url: "https://example.org/" });

在我的情况下,我将该代码添加到了我的jsdom配置文件中。var exposedProperties = ['window', 'navigator', 'document']; const { JSDOM } = jsdom; const {document } = (new JSDOM('',{ url: "https://localhost/",})).window; global.document = document;``` - p8ul
+1 虽然这不是关于Jest的特定解决方案,但它是一个替代方案,可以用于其他设置(因为这是错误代码的顶级SO,像我这样的其他人会找到这个页面,而不是使用Jest)。根据@dspacejs的好问题,这将是一个单独的文件,通过您在package.json中的测试命令调用。例如,此代码可以保存在testHelper.ts文件中,并使用mocha进行调用:scripts: { test-setup: 'mocha --compilers ts:ts-node/register,tsx:ts-nocde/register --require testHelper.ts --reporter progress' } - jmbertucci

9

我曾经遇到了同样的问题,按照这个 GitHub 线程的方法,手动安装版本为 28 的 jest-environment-jsdom 就解决了问题。


为了使其工作,我必须使用Yarn的“解析”将jest-environment-jsdom安装在与jest相同的版本上。 - Ninjakannon

8
我遇到的问题是当我将jest升级到v28.0.3时发生了。 看起来在版本28.0.0中,他们废弃了testUrl并引入了一个名为testEnvironmentOptions的对象,其中属性url具有默认值'http://localhost/'。

弃用警告:

选项“testURL”已被替换为通过“testEnvironmentOptions.url”传递URL。

请更新您的配置。

配置文档: https://jestjs.io/docs/configuration

查看PR详细信息:https://github.com/facebook/jest/pull/10797

然而,当我将jest-environment-jsdom更新并在jest.config.js文件中将testEnvironment设置为it时,我的问题消失了。

module.exports = {
  ...
  testEnvironment: 'jest-environment-jsdom',
  ...
}

1
设置 "testEnvironmentOptions.url" 对我没有起作用。但是像你说的安装 "jest-environment-jsdom" 并更新属性 "testEnvironment" 就完美解决了。谢谢! - Gustavo Cesário
为了让这个工具正常运行,我必须安装 jest-environment-jsdomyarn add --dev jest-environment-jsdom - Eric Walker

5
顶级答案中建议在我的Jest配置中添加testURL: "http://localhost"并不适用于我。然而,在jsdom GitHub讨论中的此建议,在创建jsdom对象时传递URL是有效的。
const url = 'http://localhost';

const dom = new JSDOM('<!DOCTYPE html><html><body></body></html>', { url });

3

对我来说,这个问题得到解决是通过升级至 "jest": "^24.9.0"。


3
为了解决 Jest SecurityError: localStorage 错误,您需要在 package.json 文件中添加 jest: { ... } 部分。
{

"name": "...",
"version": "..",
"main": "..",
"description": "...",
...

"jest": { "verbose": true, "testURL": "http://localhost/" },

}

0
这可能听起来有点傻,但对我来说,问题是因为我错误地使用npm update安装了随机的包。我一直在运行npm install,然后运行npm update,但我只应该运行npm install。我通过删除node_modules目录并再次运行npm install来解决了问题。

这与我有关,由于企业代理的原因,我实际上无法成功完成 npm install。因此,模式将是未完成的 npm install - Bernardo Dal Corno

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接