You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS项目引入JSEncrypt后运行报window is not defined错误如何解决

报错原因

JSEncrypt库强依赖浏览器全局对象window,而Next.js默认会在服务端执行组件渲染逻辑,服务端运行环境不存在window对象,因此触发该引用错误。你之前直接加载JSEncrypt.min.js未生效,是因为加载逻辑仍被服务端提前执行,没有限制为仅客户端运行。

修复方案

方案1:Next.js 13+ App Router 标记客户端组件

如果使用的是App Router架构,直接在所有用到JSEncrypt的代码文件最顶部添加'use client'指令,标记该文件仅在客户端执行即可:

'use client'
import JSEncrypt from 'jsencrypt'

// 后续写你的加密逻辑

注意:该指令必须放在文件所有代码的最顶部才会生效

方案2:Pages Router / 旧版本Next.js 禁用SSR导入

方法A:useEffect内异步导入

仅在客户端执行的useEffect生命周期中加载JSEncrypt:

import { useEffect, useState } from 'react'

export default function DemoPage() {
  const [encryptRes, setEncryptRes] = useState('')

  useEffect(() => {
    const runEncrypt = async () => {
      const JSEncrypt = (await import('jsencrypt')).default
      const encryptor = new JSEncrypt()
      encryptor.setPublicKey('你的RSA公钥')
      const result = encryptor.encrypt('需要加密的内容')
      setEncryptRes(result)
    }
    runEncrypt()
  }, [])

  return <div>加密结果:{encryptRes}</div>
}

方法B:动态导入组件时关闭SSR

如果加密逻辑封装在单独组件中,导入时直接禁用SSR:

import dynamic from 'next/dynamic'

// 动态导入加密组件,关闭服务端渲染
const EncryptComponent = dynamic(() => import('../components/EncryptComponent'), {
  ssr: false,
  // 可选配置:加载时的占位内容
  loading: () => <p>加载中...</p>
})

// 父组件内直接正常使用<EncryptComponent />即可

方案3:运行环境判断兜底

如果不想修改导入逻辑,可以在调用JSEncrypt前加环境判断,服务端环境跳过执行:

const encryptContent = (content, publicKey) => {
  // 服务端无window对象,直接返回空
  if (typeof window === 'undefined') return ''
  const JSEncrypt = require('jsencrypt').default
  const encryptor = new JSEncrypt()
  encryptor.setPublicKey(publicKey)
  return encryptor.encrypt(content)
}

内容的提问来源于stack exchange,提问作者Sairaj Naik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 10:45:01