在GET期间表达比赛条件

时间:2018-12-01 03:18:02

标签: angular express

我正在使用Angular / Node / Express / Psql应用程序。对于应用程序的一部分,我有GET请求去Express检索用户配置文件。我有一个名为profile-pics的文件夹,其中包含用户的图片,如果用户图片不存在,它将从数据库中检索该图片并将其插入文件夹中并返回图片。

GET URL请求的当前设置方式是通过这样的调用:

user/profile-pic?username=bar123456

它到达快速路由,即使请求两个不同的呼叫,某些呼叫也将返回相同的个人资料图片。

例如,将运行两个GET请求

user/profile-pic?username=foo123456
user/profile-pic?username=bar123456

但是两张图片都是bar123456图片。

我尝试通过编写

对其进行调试
console.log('Sending back picture ' + profilePicPath). 

这样做,我会得到

'Sending back picture bar123456'
'Sending back picture bar123456'

这是快递中返回图片的路线。我已经拿出数据库调用,因为已经有两个头像

userRouter.get('/user/profile-pic', function (req, res) {
    let userName = req.query.username;
    fileName = './profile-pics/' + userName + '.jpg';
    userProfilePic = userName + '.jpg';

    fs.exists(fileName, function (exists) {
        if (exists) {            
            console.log('Sending back picture ' + userProfilePic);
            res.status(200).contentType('image/png').sendFile(userProfilePic, {
                root: path.join(__dirname, '../profile-pics/')
            }, function (err) {
                if (err) {
                    console.log(err);
                }
            });
        }
    })
});

我还尝试了对字符串进行切片以创建新副本,因为我认为它可能只是在复制引用,并且引用已更改。但是那也不起作用。

1 个答案:

答案 0 :(得分:2)

您需要正确地将fileNameuserProfilePic变量声明为局部变量。当您不将它们声明为局部时,它们将成为隐式全局变量,并且会在不同的请求之间“共享”,这很容易导致争用情况,因为一个请求处理程序会覆盖另一个请求处理程序在使用过程中所使用的值。更改为此:

userRouter.get('/user/profile-pic', function (req, res) {
    let userName = req.query.username;
    let fileName = './profile-pics/' + userName + '.jpg';
    let userProfilePic = userName + '.jpg';

    fs.exists(fileName, function (exists) {
        if (exists) {            
            console.log('Sending back picture ' + userProfilePic);
            res.status(200).contentType('image/png').sendFile(userProfilePic, {
                root: path.join(__dirname, '../profile-pics/')
            }, function (err) {
                if (err) {
                    console.log(err);
                }
            });
        }
    })
});

P.S。您还需要在所有代码路径中发送响应,例如文件不存在或错误处理程序中。通过路由处理程序的所有路径都应调用next()或自己发送响应。

仅供参考,通过lint运行代码和/或以严格模式运行代码会使这些编程错误更加明显。