简体   繁体   中英

My nodejs api mixes the codes of simultaneous api requests by clients

I have a nodejs server file which has an api as shown below to update the profile pictures.

app.post('/updateProfilePic', async(req, res) => {
try {
    if (VerifyAPIKey(req.query.key)) {
        let userdata = users.find(e => e.Id == req.query.socketId);
        if (userdata) {
            for (var a = 0; a < users.length; a++) {
                const b = a;
                if (users[a].IsAuthenticated) {
                    if (req.query.pub) {
                        cloudinary.uploader.destroy(req.query.pub, {resource_type: 'image'}, function(err, res) {
                            // console.log(err, res);
                        });
                    }
                    cloudinary.uploader.upload(req.files.profilePic.tempFilePath, {resource_type: 'image', folder: 'members', eager: [
                        {width: 25, height: 25, g: 'face', radius: "max", crop: 'fill', format: "png"},
                        {width: 50, height: 50, g: 'face', radius: "max", crop: 'fill', format: "png"},
                        {width: 100, height: 100, g: 'face', radius: "max", crop: 'fill', format: "png"},
                        {width: 250, height: 250, g: 'face', radius: "max", crop: 'fill', format: "png"},
                        {width: 500, height: 500, g: 'face', crop: 'fill'},
                    ]}, function(err,response) {
                        if (err) {
                            console.log(err);
                        }
                        if (response) {
                            const logo = userModel.findOneAndUpdate({
                                _id: users[b]._id,
                            },{
                                PictureUrl: response
                            }, (err, result) => {
                                data.status = 200;
                                data.message = "Your Profile Picture has been updated!"
                                res.status(200).send(data);
                            })
                        }
                    });
                }
            }
        }   else    {
            data.status = 404;
            data.message = "Invalid User!";
            res.status(200).send(data);
        }
    }   else    {
        res.json('Unauthorized request!');
    }
}   catch(err) {
    res.status(400).send(err.message);
}
})

The VerifyAPIKey function is given below

function VerifyAPIKey(key) {
   var a = users.find(e=> e.API_KEY == key);
   console.log(a)
   fs.appendFile('./data/apiRequests.txt', JSON.stringify(a) + "\r\n", function (err) {
       if (err) throw err;
   });
   return Boolean(a);
}

The userdata is in a format as shown below

{
   Id: 'FjWs0GZ4MkE_GCmKAAAD',
   Ip: '::1',
   API_KEY: '590c3789-e807-431b-bfdb-e20b6649e553',
   HOST: undefined,
   IsAuthenticated: false
}

The problem is the current code causes the response data from cloudinary to mix up between simultaneous requests. I have tested it with two simultaneous requests. Out of the two cloudinary responses whichever comes first is sent back as response to the user who invoked the api later than the two. And the user who invoked the api first get's an error saying cannot set headers after they are sent.

I have tried searching for solution but haven't found any. Can someone please help?

How does data got initiated? data does not seem to be thread-safe and defined outside your async flow. You may want to start from there and make sure data is thread-safe.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM