将标头发送到客户端后无法设置标头-请帮助我在代码中理解这一点
Posted
技术标签:
【中文标题】将标头发送到客户端后无法设置标头-请帮助我在代码中理解这一点【英文标题】:Cannot set headers after they are sent to the client - Please help me understand this in my code 【发布时间】:2021-12-31 06:06:26 【问题描述】:我的 Parse 云代码中出现此错误,我不太明白 THIS SOLUTION 如何应用于我的代码,因为我正在使用 Parse 云代码。我知道服务器是一个使用 javascript 运行 Parse 的 via,然后在数据库中运行 CRUD 操作。但是因为实际的 HTTP 请求并不能真正看到它,所以我不知道发生了什么以及我应该在哪里调整我的代码。
如果有人能指出我做错了什么以及如何调整我的代码,那就太好了。这也算大事吗?如果我将像下面这样的云代码留在生产中,这会很重要吗?使用此功能,现在一切都按照高级别的结果完美运行。
我认为我应该继续使用 .then() 函数。如果是这样的话,这棵树到底能走多久?
Parse.Cloud.define("ccCreateGroupRole", async function(request)
let user = request.user.id;
let acl = new Parse.ACL();
acl.setReadAccess(request.user, true);
acl.setWriteAccess(request.user, true);
let adminRole = new Parse.Role("Group_" + user, acl);
adminRole.save(null, useMasterKey: true ).then(function()
adminRole.getUsers().add(request.user);
adminRole.save(null, useMasterKey: true ).then(function()
console.log("Role created " + adminRole.id);
);
);
// Create Sync Status objects
let masterSyncStatus = user: user, syncStatus: true;
let newUserSyncStatus = user: user, syncStatus: true;
let masterArray = [];
let newUserArray = [];
masterArray.push(masterSyncStatus);
newUserArray.push(newUserSyncStatus);
// Initialize Sync Status class object by groupID
let SyncStatus = Parse.Object.extend("SyncStatus");
let syncStatus = new SyncStatus();
syncStatus.set("groupName", "Group_" + user);
syncStatus.set("masterSyncStatus", masterArray);
syncStatus.set("newUserSyncStatus", newUserArray);
await syncStatus.save(null, useMasterKey: true );
// Write own publicKey to user class
let UserAddPublicKey = Parse.Object.extend("_User");
let userAddPublicKey = new UserAddPublicKey();
userAddPublicKey.set("objectId", request.user.id);
userAddPublicKey.save(null, useMasterKey: true );
);
【问题讨论】:
您提到的错误与尝试向同一个 http 请求发送多个响应有关,但是您没有在此代码中显示任何 http 响应的发送,所以我认为我们需要查看更多代码 - 理想情况下,它是整个请求处理程序的一部分。此外,这通常是来自 http 请求处理程序或快速路由处理程序的错误。我们需要完整地查看该处理程序。 这是有道理的,这绝对是我的问题的一部分,我不确定在使用 Parse 时如何获得它。当我得到处理程序时,我会调查并发布它。 所以,我根本不知道 Parse 系统。此代码中是否存在应该直接导致发送 http 响应的方法调用? 是的,每个调用都直接导致一个 HTTP 请求。我认为等待该功能会起作用,它确实有效,但也会引发错误......我已经解决了这个问题,请参阅下面的解决方案。现在发布。我认为在一个函数中包含许多 .then() 以执行许多操作是非常奇怪的...... 【参考方案1】:您的原始代码并未等待您的所有承诺。相反,您混合使用了await
和.then()
,但没有在任何地方正确控制流量。
当您将所有.then()
相互嵌套时,您能够正确地对所有异步操作进行排序,以便 B 等到 A 完成,C 等到 B 完成。您的原始代码没有这样做。
但是,您也可以像这样使用 await
完成所有这些操作,方法是在所有异步操作上使用 await
以确保您正在对所有内容进行排序:
Parse.Cloud.define("ccCreateGroupRole", async function(request)
let user = request.user.id;
let acl = new Parse.ACL();
acl.setReadAccess(request.user, true);
acl.setWriteAccess(request.user, true);
let adminRole = new Parse.Role("Group_" + user, acl);
await adminRole.save(null, useMasterKey: true );
adminRole.getUsers().add(request.user);
await adminRole.save(null, useMasterKey: true );
console.log("Role created " + adminRole.id);
// Create Sync Status objects
let masterSyncStatus = user: user, syncStatus: true ;
let newUserSyncStatus = user: user, syncStatus: true ;
let masterArray = [];
let newUserArray = [];
masterArray.push(masterSyncStatus);
newUserArray.push(newUserSyncStatus);
// Initialize Sync Status class object by groupID
let SyncStatus = Parse.Object.extend("SyncStatus");
let syncStatus = new SyncStatus();
syncStatus.set("groupName", "Group_" + user);
syncStatus.set("masterSyncStatus", masterArray);
syncStatus.set("newUserSyncStatus", newUserArray);
await syncStatus.save(null, useMasterKey: true );
// Write own publicKey to user class
let UserAddPublicKey = Parse.Object.extend("_User");
let userAddPublicKey = new UserAddPublicKey();
userAddPublicKey.set("objectId", request.user.id);
await userAddPublicKey.save(null, useMasterKey: true );
);
【讨论】:
感谢您指出这一点。问题解决了,理解也增加了。 @RobbB - 这里的错误处理怎么样?如果您正在等待的任何承诺被拒绝怎么办? Parse 会抓住拒绝并做一些可以理解的事情吗?还是您必须抓住拒绝并采取适当的措施? 我目前正在检查我所有的云代码并处理可能的错误。最初我关心的是学习 javascript,现在是重构时间。【参考方案2】:我不确定这是否是“javascript 正确”,但我将许多 .then() 链接在一起,并且不再出现错误。我不明白为什么我之前使用的 async/await 不起作用......但这解决了我的主要问题。
编辑:async/await 确实有效,但我在 Parse 日志中收到错误。
谁能更好地解释这一点?如果是这样,正确的答案仍然存在。
Parse.Cloud.define("ccCreateGroupRole", async function(request)
let user = request.user.id;
let acl = new Parse.ACL();
acl.setReadAccess(request.user, true);
acl.setWriteAccess(request.user, true);
let adminRole = new Parse.Role("Group_" + user, acl);
adminRole.save(null, useMasterKey: true ).then(function()
adminRole.getUsers().add(request.user);
adminRole.save(null, useMasterKey: true ).then(function()
console.log("Role created " + adminRole.id);
// Create Sync Status objects
let masterSyncStatus = user: user, syncStatus: true ;
let newUserSyncStatus = user: user, syncStatus: true ;
let masterArray = [];
let newUserArray = [];
masterArray.push(masterSyncStatus);
newUserArray.push(newUserSyncStatus);
// Initialize Sync Status class object by groupID
let SyncStatus = Parse.Object.extend("SyncStatus");
let syncStatus = new SyncStatus();
syncStatus.set("groupName", "Group_" + user);
syncStatus.set("masterSyncStatus", masterArray);
syncStatus.set("newUserSyncStatus", newUserArray);
syncStatus.save(null, useMasterKey: true ).then(function()
// Write own publicKey to user class
let UserAddPublicKey = Parse.Object.extend("_User");
let userAddPublicKey = new UserAddPublicKey();
userAddPublicKey.set("objectId", request.user.id);
userAddPublicKey.save(null, useMasterKey: true ).then(function()
console.log("Save success");
);
);
);
);
);
【讨论】:
以上是关于将标头发送到客户端后无法设置标头-请帮助我在代码中理解这一点的主要内容,如果未能解决你的问题,请参考以下文章
将标头发送到客户端后无法设置标头-Nodejs + AWS-S3 getObject
节点 JS:错误 [ERR_HTTP_HEADERS_SENT]:在将标头发送到客户端后无法设置标头