NodeJS 加密.randomUUID()不适用于Next.js v13

rslzwgfq  于 2023-01-30  发布在  Node.js
关注(0)|答案(2)|浏览(226)

环境

    • 下一个. js v13**(* 稳定 *,编号./app文件夹)正在 * Ubuntu * WSL中与节点v18一起运行。

根据文件,加密API已经出现,因为节点v14~ish。
这确实已经在我的环境中的Node中进行了测试:Node 18 importing and running crypto.randomUUID()我还打印了整个对象,它看起来像文档所说的那样。

问题

想象一下这个简单的组件:

import crypto from 'crypto';

export default function Crypto() {
  console.log(crypto);

  return (
    <p>
      {crypto.randomUUID()}
    </p>
  );
}

Next.js说它"在397毫秒内成功地编译了客户端和服务器",但是在UUID在浏览器中呈现了几毫秒之后,Next.js抛出了几个错误,这些错误围绕着 * randomUUID不是一个函数 *。
Next Runtime Error with crypto.randomUUID()
我看到Webpack有点混在里面;我没有试用过Turbopack。它超出了本期的讨论范围。
在注解掉段落中的方法调用之后,console. log(crypto)像往常一样在devtools中运行并打印两次,如下所示:crypto method printed
注意一个来自react devetools backend,另一个来自webkpack,这让我相信这个错误是在服务器端抛出的,因为console. loglog在UUID方法之前被调用。
服务器端,尽管浏览器中抛出错误,Next CLI仍会打印该对象,并且该对象包含以下方法:Next CLI prints crypto object and randomUUID is listed
在客户端,在打印的对象中,找不到方法randomUUID():Inside printed crypto object in devtools这确认了错误消息。我的代码无法访问该方法。此外,与节点文档相比,缺少了几个方法。
然而,如果直接从devTools创建一个console.log(crypto),它的原型中确实有这个方法:
randomUUID directly from devtools
此外,由于结构的原因,我倾向于相信打印的加密对象是以某种方式来自Node的,因为Chrome V8加密对象的结构是完全不同的。
我尝试了console. logging对象服务器端,客户端,和中间。不知怎么的,方法在中间丢失了。Webpack可能是罪魁祸首。最糟糕的是,虽然只是一眨眼的功夫,我可以看到字符串呈现之前的错误抛出;并且消 debugging 误卡会抛出一个空的主体。字符串会消失。

    • EDIT**导入/需要加密的原因是为了在Node中运行。接下来是SSR框架;简而言之,它应该首先在服务器上运行,然后尽可能多地以HTML的形式呈现和交付给客户端。如果没有导入,当Next试图调用Crypto服务器端时,Node会抛出一个错误。

现在,我告诉这段代码只有在Window对象可用(即我在浏览器中)时才运行,并且它与本机chromium V8 Crypto对象一起运行。

// import crypto from 'crypto';

export default function Crypto() {
  if (typeof window !== 'undefined') {
    console.log('CLIENT: ', crypto.randomUUID());

    return (
      <p>
        {crypto.randomUUID()}
      </p>
    );
  }

  return (
    <h1>SERVER SIDE</h1>
  );
}

唯一的缺点是,不知何故,仍然运行了两次Next magic的bc,一次是服务器端,一次是客户端,这意味着它不是React 18的bc。它准确地告诉我,作为UUID函数的

总是返回不同的结果。

zxlwwiss

zxlwwiss1#

当不在安全上下文(如defined here)中运行时,浏览器会限制对某些加密API的访问。

b4lqfgs4

b4lqfgs42#

当页面最初加载时,在useEffect挂钩中将其设置为state,以便它持久化,然后从state呈现它。

const Crypto = () => {
 const [randomUUID, setRandomUUID] = useState();

 useEffect((
  if (typeof window !== 'undefined' && !randomUUID) {
   setRandomUUID(crypto.randomUUID());
  }
 ),[]);

 if(!randomUUID) <>No UUID</>;
 return <>{randomUUID}</>
}

export default Crypto;

相关问题