【问题标题】:How does my server (or user agent?) look up static files?我的服务器(或用户代理?)如何查找静态文件?
【发布时间】:2022-01-27 11:42:12
【问题描述】:

我只是想知道,在属于某个 json 对象的文件系统上检索保存的图像究竟是如何工作的?例如,当我正在创建具有图像的产品并将图像与新创建的产品一起上传时,我通常将图像保存在我的服务器后端文件系统上的某个文件夹中,然后保存返回的图像保存路径和将其作为字符串字段存储在我的产品 json 对象中。

现在它在客户端是如何工作的,例如,如果我想检索相同的图像并将其显示在产品卡上的图像 src 属性中,然后在浏览器中显示它,它必须查找图像源在服务器的静态资产文件夹(我存储图像的地方),对吧?

我将图像 url 作为字符串保存到我的产品中(这是 json 数据)。该图像字符串路径必须与我的静态文件夹的路径名匹配才能真正获得真实图像。但这真的有效吗?我的意思是图像是字节数据,必须由服务器检索,首先,它必须知道在哪里查找资产,然后解析并将它们发送回浏览器,或者不是(或者实际上是客户端在幕后以某种方式检索它)?当我说:

app.use("/uploads", express.static(path.join(__dirname, '/uploads'))) 

如果我的前端不是直接从我的 node.js 应用程序提供的,那么图像检索是否真的有效,假设我的后端驻留在单独的云服务器上,而我的前端驻留在其他云服务器上,它如何检索真实的那么图片呢?

【问题讨论】:

    标签: node.js file-upload static assets data-retrieval


    【解决方案1】:

    当客户端将图像上传到服务器时,它必须以服务器能够在未来某个时间通过某个已知 URL 将该图像提供给客户端的方式进行。如果服务器只是将图像放到服务器上的文件夹中并且服务器正在为该文件夹中存在的所有静态资源提供服务,那么服务器只需要知道如何重建将导致服务器找到它并提供服务的 URL它从该文件夹中,以便它可以将该 URL 嵌入到它生成的 HTML 页面中。这只是您同意的一些约定。您在问题中显示的一行代码表明您的约定是/uploads/somefilename 作为 URL。

    注意,这有一个问题,如果所有客户端上传都在完全相同的目录中,那么您必须确保没有两个上传具有相同的文件名,或者如果您在服务器上生成唯一的文件名当您上传时,客户端需要这种机制来了解或获取该文件名或 URL 应该是什么,以便将来可以请求它。

    假设客户正在上传您希望稍后能够从网页中显示的个人资料图片。步骤如下:

    1. 客户使用表单发布上传个人资料图片。
    2. 服务器接收图像,以任何必要的方式对其进行处理(例如将其调整为个人资料图像的理想图像大小)并存储在uploads 文件夹中。该文件唯一命名为username-profile.jpg,其中用户名是您登录系统中客户端的唯一用户名。这保证了文件名是唯一的,并且可以为特定用户制作。
    3. 当生成一些未来的网页时,服务器希望嵌入个人资料图片。使用登录用户的用户名,他们构建一个 URL 并将其放在生成的网页中的 <img> 标记中,例如:<img src="/uploads/someusername-profile.jpg">
    4. 浏览器获取该网页,看到<img> 标签并向服务器发送https://yourhost/uploads/someusername-profile.jpg 的请求。
    5. 您的服务器看到 /uploads 前缀并让 express.static 在该目录中找到 someusername-profile.jpg,找到后将图像流式传输回浏览器。
    6. 浏览器显示它获得的图像。

    现在它在客户端是如何工作的,例如,如果我想检索相同的图像并将其显示在产品卡上的图像 src 属性中,然后在浏览器中显示它,它必须查找图像服务器的静态资产文件夹(我存储图像的位置)上的源,对吗?

    我认为这在上面的步骤中有所描述。

    我将图像 url 作为字符串保存到我的产品中(即 json 数据)。该图像字符串路径必须与我的静态文件夹的路径名匹配才能真正获得真实图像。但这真的有效吗?我的意思是图像是字节数据,必须由服务器检索,首先,它必须知道在哪里查找资产,然后解析并将它们发送回浏览器,或者不是(或者实际上是客户端以某种方式在幕后检索它)?

    您的服务器将生成带有适当<img> 标记的 HTML,其中包含一个 URL,当浏览器请求该 URL 时,您的服务器将发送所需的图像。因此,您在服务器上的 HTML 中嵌入和 <img> 标记,并将该 HTML 作为浏览器某些页面请求的一部分发送到客户端。然后浏览器解析 HTML,找到 <img> 标记,从该标记中获取 src 值并向服务器发送另一个请求以获取该图像 URL。服务器收到该请求,并且您的express.static() 中间件代码行将该请求与您服务器上的特定文件相匹配,并将图像数据发送回浏览器。当浏览器收到图片数据后,会在你的网页中显示图片。

    如果客户端试图通过 Javascript 调用直接检索图像,则客户端必须通过某种方式知道要从服务器请求哪个 URL,以便响应所需的图像。

    当我说:app.use("/uploads", express.static(path.join(__dirname, '/uploads'))) 时,我的服务器上会发生什么。

    该行代码告诉 Express 获取以 /uploads 路径开头的任何 URL,并在您的服务器端 /uploads 目录中查找与请求的其余部分中指定的文件名相同的文件名网址。因此,如果请求的 URL 是 https://yourhost/uploads/myfile.jpg,那么由于您声明 express.static() 中间件的方式,它会在您的 /uploads 文件夹中查找 myfile.jpg 文件。如果找到,它将接管 http 请求并将图像数据流式传输回客户端。如果没有找到,路由将继续到其他路由,如果在任何其他路由中没有找到匹配项,express 将返回 404 http 状态。

    如果我的前端不是直接从我的 node.js 应用程序提供的,那么图像检索是否真的有效,假设我的后端驻留在单独的云服务器上,而我的前端驻留在其他云服务器上,它如何检索真实的那么图片呢?

    生成嵌入了<img> 标记的HTML 应该包含src 属性和对应于实际图像的URL,必须知道该图像的正确URL 是什么。如果生成 HTML 的服务器与提供图像的主机不同,则它必须生成指向适当主机的 URL。如果它是同一个主机,那么它可以完全从 URL 中省略域,浏览器将从包含 <img> 标记的网页中替换域。但是,如果它是不同的主机,那么您必须将包括协议和主机在内的整个完整 URL 放在:

    <img src="https://mycloudhost/uploads/someimage.jpg">
    

    【讨论】:

    • 非常好,清晰,谢谢,我明白了大部分。就在你说它“流”回图像数据时,你到底是什么意思?它实际上是否通过单个 http(我假设 http 2.0)连接将真正的字节数据块流回客户端?甚至在插座上?我的意思是,有不同的方式来显示图像,例如,使用数据 url 作为字符串,或者可能只是字节数据,然后将其解释为图像,我假设。你能告诉我更多关于它在幕后是如何工作的,以便它被识别为图像吗?我认为 MIME_TYPE 也在那里发挥作用..
    • @ChillaBee - 它只是发送带有适当标题的图像的二进制数据来识别内容类型。 “流式传输”是指从存储中读取数据并以块的形式发送数据的过程(而不是将其全部读入内存)并注意来自传输和接收者的流控制信号,这样您就不会使他们的接收能力或网络过载管道传输字节的能力。
    猜你喜欢
    • 2015-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    • 2019-08-29
    • 1970-01-01
    • 2015-06-05
    • 2012-05-17
    相关资源
    最近更新 更多