控制台出现GeneratorFunctionPrototype错误且无法添加Session/Cookie求助
一、控制台出现GeneratorFunctionPrototype { _invoke: [Function: invoke] }错误的原因及解决
首先,这个错误通常是因为你的authCrud.single或者authCrud.create方法返回的是Generator函数,而非标准的Promise对象。虽然你用了await来等待结果,但await只能处理Promise,对Generator函数无效,所以控制台会抛出这个原型相关的错误。
为什么功能还能正常运行?大概率是你的代码逻辑没有严格依赖这个错误返回的结果,或者框架内部悄悄做了兼容,但这个错误本身还是会暴露在控制台里。
解决方法很直接:
- 如果你用的是基于Generator的CRUD库(比如早期的mongoose或者自定义的yield风格代码),可以用
co库把Generator函数转换成Promise,比如:const co = require('co'); auth = await co(authCrud.single({ $or: [{ username }, { email: username }] })); - 更彻底的方式是重构
authCrud的方法,让它们返回Promise。比如把Generator函数改成async函数,或者用Promise.resolve()包裹原有的yield逻辑,这样await就能正常处理了。
二、无法添加Session或Cookie的排查方向
咱们从几个常见的点逐一排查:
1. 检查Session中间件的配置
如果你用的是Koa框架(从ctx的用法来看大概率是),必须确保Session中间件在路由之前正确注册。比如使用koa-session的话,配置应该是这样的:
const Koa = require('koa'); const session = require('koa-session'); const app = new Koa(); // 必须设置密钥,用于加密Session app.keys = ['your-strong-secret-key-here']; // 注册Session中间件,要在路由之前 app.use(session({ // 可选配置:比如cookie的过期时间、httpOnly等 maxAge: 86400000, // 1天 httpOnly: true, }, app));
如果中间件没注册或者顺序错了,ctx.session根本不会生效。
2. 跨域请求的Credentials配置
如果你的前端和后端是跨域的,必须同时满足两个条件:
- 前端请求时要带上
credentials: true(比如Axios中设置withCredentials: true) - 后端要设置响应头:
ctx.set('Access-Control-Allow-Credentials', 'true'); ctx.set('Access-Control-Allow-Origin', 'http://your-frontend-domain.com'); // 不能是*
如果缺了任何一个,浏览器都会拒绝保存Cookie/Session。
3. Cookie属性的合理性
如果是直接设置Cookie(而非通过Session),要检查这些属性:
domain:必须和前端域名一致,不能跨域path:默认是/,一般没问题,但如果设置了特定路径,要确保请求路径匹配secure:生产环境下如果用HTTPS,需要设为true,但本地HTTP环境要设为false,否则Cookie不会被保存httpOnly:设为true可以防止XSS,但如果前端需要读取Cookie,要设为false
4. 代码执行顺序与错误分支
看你的代码,ctx.session._token = auth._id;是在所有错误分支之后执行的——也就是说,只有当用户登录/注册成功、没有抛出ctx.throw的情况下,这段代码才会执行。你可以在这行代码后面加个console.log(ctx.session),确认是否真的执行到了这里,以及Session是否被正确赋值。
5. Session存储的问题
如果你用了外部存储(比如Redis)来存Session,要确保存储服务正常运行,并且中间件的配置正确(比如koa-generic-session搭配koa-redis时,要正确连接Redis)。如果存储挂了,Session也无法正常保存。
内容的提问来源于stack exchange,提问作者Smit Ray

