【问题标题】:Running Flask locally. I want to display images based on names generated in JavaScript在本地运行 Flask。我想根据 JavaScript 中生成的名称显示图像
【发布时间】:2013-09-25 13:47:46
【问题描述】:

我正在使用 d3 和 Flask 在我的浏览器中显示树形图。整个东西在本地存储和操作。

我想在用户将鼠标悬停在树形图中的每个节点上时显示相关图像。

对于树形图所基于的 JSON 数据,我使用的是 url_for 和我的静态文件夹,如下所示:

d3.json("{{ url_for('static', filename=json_data) }}", function(error, flare) {
    // Lots of code

包含 d3 也是一样:

<script src="{{ url_for('static', filename='d3.js') }}"></script>

但是,当涉及到我希望在悬停时出现的图像时,我使用来自 JSON 的数据来创建图像的名称。因为这意味着使用 JavaScript 变量而不是 python 变量,所以我看不到如何使用 url_for 显示它。

作为替代方案,我尝试使用一系列不同的绝对和相对路径,但没有任何效果。我读了一些关于 Firefox 不想显示本地文件的内容,但这肯定不适用于在我的计算机上运行的东西吗?我可以在浏览器中正常显示大量本地文件。无论哪种方式,我都安装了一个名为 LocalLink 的附加组件。这是我尝试使用此方法的代码:

var img_path;
d3.selectAll( ".node" ).on( "mouseover", function(d) {
  img_path = "{{ image_path }}" + d.name + ".png";
  document.getElementById('thumb').src=img_path;
  document.getElementById('thumb').style.display='block';

这里,python image_path 变量类似于 r"file:///C:/Python27/my/app/folders/etc/"

这几乎可行。图像不会出现在悬停时,但如果我使用 Firebug 并将鼠标悬停在 HTML 中的适当标签上,正确的图像会在我的光标旁边显示为缩略图。

我尝试使用引用“file:///.....”位置的图像创建一个简单的 HTML 页面。这样可行。这让我觉得这个方法的问题是 Flask。网站位置的绝对路径似乎没有问题(我已经测试过,它有效),所以我猜测 Flask 不喜欢本地文件位置的绝对路径。

因此,有几种解决方法的可能性:

  • 有一种方法可以将 url_for 与 JavaScript 中生成的变量一起使用。
  • 有一种方法可以将信息传回 Python 变量并在 url_for 中使用。
  • 有一种方法可以让 Flask 使用“file:///.....”格式显示这些图像。

还有其他方法吗?

我考虑过的唯一其他选择是将整个事情转移到网上。但是,我对 Python 托管不是很熟悉,而且这个应用程序使用了 Twisted 和 PyQT。我不知道如何将它们安装在服务器上。我什至不知道我构建的内容是否可以在线使用 - 你可以在实时网站上使用 Twisted 或 PyQT 吗?我对 Twisted 的所作所为只有一个模糊的认识。

如果人们认为这是我最好/唯一的选择,我将详细解释我的应用程序是如何工作的,但在此之前我不会把事情搞得一团糟。

【问题讨论】:

    标签: javascript python python-2.7 flask


    【解决方案1】:

    我假设您正在本地运行 Flask 应用程序(在您的浏览器中,您正在输入类似 localhost:8000 的内容)。

    首先,您需要了解url_for 的作用。它可以帮助您生成 HTML 需要加载的静态文件(在您的情况下为图像或 javascript 源文件)的 URL。所以,当你有...

    <script src="{{ url_for('static', filename='d3.js') }}"></script>
    

    ...模板引擎实际上将其转换为...

    <script src="/static/d3.js"></script>
    

    如果您愿意,您可以在模板中输入以上内容(但如果您需要将路径更改为 /media 而不是 /static,则使用 url_for 会很有帮助:现在您只需将其更改为一个地方,而不是更改所有链接)。

    因此,这意味着当您运行 Flask 并使用上述 HTML 加载页面时,浏览器知道在“localhost:8000/static/d3.js”中找到 d3.js 脚本。浏览器向服务器(你的flask应用程序)发送请求,Flask识别它正在寻找一个静态文件(因为路径以/static开头)并返回存储在static目录中的d3.js文件你的项目。

    现在,假设您的/static 目录中有一个名为static/images/img1.png 的文件。要显示此内容,您需要生成与此图像相关的 URL(即/static/images/img1.png)。在 Flask 中,您通常会键入:

    <img src="{{ url_for('static', filename='img/img01.png') }}"></img>
    

    ...这将转化为...

    <img src="/static/img/img01.png"></img>
    

    如果您愿意,只需输入此 URL。因此,您的 javascript 可以只生成这个 URL 并且它会工作。

    现在,也许您已经知道这一点,但困扰您的是为什么您不能执行类似file:///C:/Python27/my/app/folders/etc/ 的操作。首先,您说 Flask 没有按您的预期处理此请求。好吧,那是因为 Flask 根本没有处理这个请求!请记住,Flask 是在 localhost:8000 之类的东西上运行的。如果您键入&lt;img src="file:///C:/Python27/my/app/folders/etc"&gt;&lt;/img&gt;,则浏览器不会向localhost:8000 发送检索此文件的请求,而是尝试使用浏览器在本地检索文件。同样,如果您的页面上有google.com 的链接,您的浏览器不会将点击该链接的用户发送到您的烧瓶应用程序,他们会将其发送给 Google!

    出于安全原因,如果您连接到的网站不是本地站点(例如,example.com/index.html 而不是file:///home/mark/index.html),Firefox 将not allow you access files directly from the disk。这是有道理的,因为否则访问 example.com,该网站可以将您硬盘上的任何文件加载到 javascript 可以访问的网页中,然后将该文件的信息发送回该网站!

    碰巧localhost:8000 被认为是浏览器的非本地站点。因此,Firefox 将不允许您从该页面访问那些 file:///... 资源。

    所以,这不是 Flask 的问题:这是使用浏览器做浏览器不想做的事情的问题。

    现在,您的解决方案究竟是什么将取决于您的应用程序的需求。最直接的解决方案是让您要显示的图像位于项目的/static 目录中。

    但是,如果您想创建一个 Flask 项目来处理放置在硬盘驱动器上任何位置的文件(没有先从“上传”页面从中选择文件),那么您可能选择了错误的工具(一个基于 Web 的应用程序)。

    【讨论】:

    • 有效!谢谢你的解释。我不知道 url_for 只是在构建这样的 url。但是,我确信我已经为此尝试了所有合理、合理的 url 路径,但显然我错过了正确的路径。
    猜你喜欢
    • 2021-01-19
    • 1970-01-01
    • 2015-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    • 2020-01-16
    • 1970-01-01
    相关资源
    最近更新 更多