【问题标题】:Major images conundrum - Node.js Express server主要图像难题 - Node.js Express 服务器
【发布时间】:2016-05-16 18:28:27
【问题描述】:

所以我们有一个带有 Node.js 的后端工具,可以抓取 HTML 网页的 img 标签。我们使用工作者 child_process 执行此操作,以免阻塞主进程。我们在服务器上这样做的原因是因为我们在尝试使用 AJAX / 使用 Angular $http 访问 HTML 页面时遇到了 CORS 问题。

当后端网络爬虫完成后,它可以向浏览器发送一个 url 列表。浏览器可以对与这些 url 相关的图像发出 AJAX 请求,但据我所知,前端会遇到与检索 HTML 相同的 CORS 问题。

所以我们目前对这个问题有一个相当糟糕的解决方案。我们使用 Cloudinary 来完成繁重的工作,而不是我们的 Node.js 服务器处理 base64。后端工作者 child_process 抓取 HTML,获取图像 url,然后向 Cloudinary 发送请求以检索图像并将新的 Cloudinary url 发送回我们的服务器。然后我们将 Cloudinary url 发送到前端,前端可以访问这些 Cloudinary url 而不会出现任何 CORS 问题。

这样做有两个问题:

  1. 这相当慢 - 抓取大约需要 2 秒,然后等待 Cloudinary 保存图像并响应另一个 2-4 秒。所以浏览器需要等待大约 4-6 秒。
  2. 我们最终在 Cloudinary 中存储了大量图像,这将变得昂贵。我们最终可以删除我们保存的大约 90% 的图像 在此过程之后立即,因为用户只会 选择出现在浏览器中的图像之一,但我们是 担心即使图像可能会产生的成本 在 Cloudinary 上停留几秒钟。

有没有人遇到过这些问题并认为他们有比我们使用的更好的解决方案?

【问题讨论】:

  • 为什么客户端必须通过 Ajax 请求图像?如果您只想在网页中显示图像,则通过 <img> 标签加载图像没有跨域限制。
  • 啊非常有趣...所以我们可以动态地将 img 标签插入到我们的前端 html 给定从我们的服务器发送的 url 列表,这将加载图像的预览...是对吗?
  • 我不是真正的前端开发人员,所以我对此了解不多!
  • 是的,没错。您的服务器可以将 URL 提供给前端。然后,前端可以在其中插入带有正确 URL 的 <img> 标签,无论它们来自哪个来源,它们都会显示在页面中。我将此评论放在下面的答案中。

标签: javascript angularjs node.js image cloudinary


【解决方案1】:

将抓取的图像列表返回给您的客户端,然后使用您的 nodejs 服务器作为代理来提供这些图像。

这是一个使用 request 模块的简单示例:

http.createServer(function (req, resp) {
  var x = request('http://example.com/image.png')
  req.pipe(x)
  x.pipe(resp)
})

您的客户将可以访问任何所需的图像:

domain.com/proxy?url=http://example.com/image.png

【讨论】:

  • 谢谢,但这不会给 node.js 服务器带来很大的负担吗?
  • 也可能只需要做 request(url).pipe(res)。
  • 是的。您可能需要考虑使用与主网络服务器不同的代理服务器。
  • 感谢这可能是一个解决方案 - 您是否知道为什么代理服务器可以访问其他服务器的内容而前端却不能?它只是 XmlHttpRequest 的规则吗?有办法解决吗?
  • 我可以解释的最好方法是浏览器只是决定通过阻止对未明确授予它们权限的服务器的请求来玩得很好(如果未设置 CORS 标头,则无法解决此问题预检响应)。您没有理由不能使用您编写的某些脚本(或者在您的情况下是代理服务器)发出相同的请求。
【解决方案2】:

将我的评论变成一个答案,因为它看起来可能是你的解决方案。

您可以让服务器从页面中抓取图像 URL,然后将 URL 列表发送给客户端。然后,客户端可以使用这些 URL 将 <img> 标签动态插入到当前页面中,并且浏览器将显示图像。

<img> 标签 URL 没有跨域限制。

这样做,无需尝试使用 Ajax 从客户端下载图像,因此不会出现 CORS 问题。您的服务器执行跨源抓取。然后客户端只需插入<img>标签,其中包含抓取的URL。


这种技术“借用”其他网站的图像,然后使用它们的带宽将它们显示在您的页面中。您可能应该确保允许使用这些图像。

【讨论】:

  • 经过一番研究,如果我使用 var img = new Image(); 似乎仍然存在一些跨域限制img.src ="example.com" img.onload=function(){}; ....除了使用实际的 img 标签之外,是否还有更多限制?
  • @AlexMills - 正如我在回答中所说的“<img> 标签 URL 没有跨域限制。”由浏览器强制执行。提供图像的站点可能需要请求中的某些内容(例如 auth cookie)或某个引荐来源。如果您在进行这项工作时遇到问题,我们必须检查确切的 URL 以提供更多信息。
  • 是的,我明白了
  • 任何想法如果使用 iframe 并将图像从 iframe 发送到主线程可能会有更多的运气吗?
  • @AlexMills - 我不明白你还在试图解决什么问题。如果您的 img URL 在跨源时无法使用,请发布其中一个 URL,以便我们查看服务器返回的内容,并请发布指向该图像可以使用的页面的链接,以便我们可以查看确实有效的请求。答案在于这两种情况有什么不同,对实际请求和响应的分析可以得出线索。
猜你喜欢
  • 1970-01-01
  • 2022-01-13
  • 2019-03-15
  • 2015-07-01
  • 2014-08-16
  • 1970-01-01
  • 2018-07-17
  • 2018-01-12
  • 1970-01-01
相关资源
最近更新 更多