Safari没有';通过p5 loadImage()请求图像时,不向Express发送cookie 背景

Safari没有';通过p5 loadImage()请求图像时,不向Express发送cookie 背景,express,safari,p5.js,express-session,Express,Safari,P5.js,Express Session,我在代理后设置了一个Express.js应用程序,允许用户在被引导到web应用程序之前登录。此应用程序无法在Safari(macOS/iOS)中提供某些图像,因为Safari没有将cookie与源自我的p5.js代码中的loadImage()方法的图像请求一起发送回。这不会发生在Chrome(macOS)上 当我加载页面时,浏览器会请求资源。但来自我的应用程序的请求返回一个不同的会话,该会话未登录,并被Express捕获: // Request for the main page by the

我在代理后设置了一个Express.js应用程序,允许用户在被引导到web应用程序之前登录。此应用程序无法在Safari(macOS/iOS)中提供某些图像,因为Safari没有将cookie与源自我的p5.js代码中的
loadImage()
方法的图像请求一起发送回。这不会发生在Chrome(macOS)上

当我加载页面时,浏览器会请求资源。但来自我的应用程序的请求返回一个不同的会话,该会话未登录,并被Express捕获:

// Request for the main page by the browser
Session {
  cookie:
   { path: '/',
     _expires: 2020-05-04T16:26:00.291Z,
     originalMaxAge: 259199998,
     httpOnly: true,
     secure: true },
  loggedin: true }

// Request for image assets by a script in my application
Session {
  cookie:
   { path: '/',
     _expires: 2020-05-04T16:26:00.618Z,
     originalMaxAge: 259200000,
     httpOnly: true,
     secure: true } }
来自Safari的HTTP请求 快速应用 该应用程序设置在HTTPS代理之后,因此我将Express Session对象设置为trust proxy,并将security设置为auto(设置为false不会解决问题):

当用户登录时,它将被发送到
/auth
,以对照数据库进行检查

app.post('/auth', function (request, response) {
    var user = request.body.user;
    var password = request.body.password;

    if (user && password) {
        connection.query('SELECT * FROM accounts WHERE user = ? AND password = ?', [user, password], function (error, results, fields) {
            if (results.length > 0) {

                request.session.loggedin = true;

                // If the user logs in successfully, then register the subdirectory
                app.use("/app", express.static(__dirname + '/private/'));

                // Then redirect
                response.redirect('/app');
            } else {
                response.send('Incorrect password!');
            }
            response.end();

            if (error) {
                console.log(error);
            }
        });
    } else {
        response.send('Please enter Username and Password!');
        response.end();
    }
});
登录时,它们会重定向到
/app

app.all('/app/*', function (request, response, next) {

    if (request.session.loggedin) {    
        next(); // allow the next route to run
    } else {
        // The request for images from my p5 script fails and these request redirect to "/"
        response.redirect("/");
    }
})
问题: 如何确保Safari将会话cookie与其请求一起传递,以便Express返回正确的资产


编辑 包括调用
loadImage()
的函数。这嵌入在ES6类中,该类为化学模拟中的粒子加载图像资源。此类必须成功解析承诺,以便其他高阶类可以设置正确的属性

loadParticleImage() {

    return new Promise((resolve, reject) => {

        loadImage(this.imageUrl, (result) => {

            // Resolves the Promise with the result
            resolve(result);

        }, (reason) => {

            console.log(reason);
        });
    })
}
编辑#2 将成功请求的标题直接包含到映像资产的URL:

GET https://mydomain/app/img/svg/Water.svg HTTP/1.1
Host: mydomain
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Cookie: connect.sid=s%3A2frOCv41gcVRf1J4t5LlTcWkdZTdc8NT.8pD5eEHo6JBCHcpgqOgszKraD7AakvPsMK7w2bIHlr4
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1 Safari/605.1.15
Accept-Language: en-us
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
我建议使用来服务静态文件。这样,您就不需要任何会话来获取图像、js、css等。此外,它还可以加速您的应用程序。你需要一个地方

app.use(express.static( ... )) 
应用程序之前。如果您想要一些额外的性能,请使用(session(…)
语句,因为如果这样做,express将不会尝试为静态文件创建会话。

我建议使用来服务静态文件。这样,您就不需要任何会话来获取图像、js、css等。此外,它还可以加速您的应用程序。你需要一个地方

app.use(express.static( ... )) 
应用程序之前。如果您想要一些额外的性能,请使用(session(…)
语句,因为如果您这样做,express将不会尝试为静态文件创建会话。

为该
加载映像()
函数调用中的
获取()
调用不是控制请求中是否包含cookie的设置,因此,它们不会随请求一起发送

在提供映像之前,您真的需要身份验证吗?如果没有,您可以重新安排在服务器中提供图像的方式,以便使用
express.static()
指向只包含无需验证即可提供的资源的目录,无需验证即可提供图像。如果确实需要对它们进行身份验证,您可能需要修补
loadImage()
代码以使用
凭据:包括
选项或以不同的方式加载图像。

为该
loadImage()在中调用
fetch()
功能不是控制请求中是否包含cookie的设置,因此它们不会随请求一起发送



在提供映像之前,您真的需要身份验证吗?如果没有,您可以重新安排在服务器中提供图像的方式,以便使用
express.static()
指向只包含无需验证即可提供的资源的目录,无需验证即可提供图像。如果确实需要对它们进行身份验证,您可能必须修补
loadImage()
代码才能使用
凭据:包括
选项或以其他方式加载图像。

请显示
loadImage()
客户端代码。您已经显示了失败请求的标题。请同时显示正确请求的标题。Hi@jfriend00我添加了特定的函数调用。它非常简单,返回一个承诺,用于解析
loadImage()的结果
以便其他类等待访问属性,直到它们被定义为止。@CoderFF当我直接在浏览器中访问文件时,我在编辑2中包含了成功的标题。我要求从浏览器发送GET请求的实际代码,但您仍然没有显示。我想看看实际的Ajax调用。您仍然没有显示。请显示
loadImage()
客户端代码。您已经显示了失败请求的标题。请同时显示正确请求的标题。Hi@jfriend00我添加了特定的函数调用。它非常简单,返回一个承诺,用于解析
loadImage()的结果
以便其他类等待访问属性,直到它们被定义为止。@CoderFF当我直接在浏览器中访问文件时,我在编辑2中包含了成功的标题。我要求从浏览器发送GET请求的实际代码,但您仍然没有显示。我想看看实际的Ajax调用。您仍然没有显示出来。我最初尝试过这样做,但现在我意识到我正在为应用程序的根提供服务(使登录会话变得毫无意义)。我没有想到有选择地将子文件夹作为静态文件夹提供。这解决了这个问题。我删除了所有的评论。我最初试图这样做,但现在我意识到我正在为应用程序的根提供服务(使登录会话变得毫无意义)。我没有想到有选择地将子文件夹作为静态文件夹提供。这解决了问题。我删除了所有的评论。啊,好的,这很有意义。我将向p5团队指出这一点,因为我相信其他人在Safari上也会遇到同样的问题。@dfd0226-我很好奇,弄清这里实际发生的事情的答案被认为不是你最有用的答案?啊,好的,这是有道理的。我将向p5团队指出这一点,因为我相信其他人在Safari上也会遇到同样的问题。@dfd0226-我很好奇,能够弄清这里实际发生的事情的答案并不被认为是你的答案
app.use(express.static( ... ))