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
相关产品推荐
相关产品推荐

