就地运行Flask。我想显示基于JavaScrip中生成的名称的图像

2024-05-17 13:48:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用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>

但是,当涉及到我想在hover上显示的图像时,我使用JSON中的数据来创建图像的名称。因为这意味着使用JavaScript变量而不是python变量,所以我看不到如何使用url来显示它。

作为替代,我尝试过使用一系列不同的绝对和相对路径,但都没有奏效。我读到一些关于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中相应的标记上,则正确的图像会显示为光标旁边的缩略图。

我试过创建一个简单的HTML页面,其中的图像指向“file:///…”位置。那很有效。这让我觉得烧瓶才是这种方法的问题所在。它似乎对web位置的绝对路径没有问题(我已经测试过了,它可以工作),所以我猜Flask不喜欢到本地文件位置的绝对路径。

因此,有几种可能性可以解决这个问题:

  • 有一种方法可以对JavaScript中生成的变量使用url。
  • 有一种方法可以将信息传递回python变量,并在url中使用它。
  • 有一种方法可以让Flask使用“file:///…”格式显示这些图像。

还有别的办法吗?

我唯一考虑的另一个选择是把整个事情搬到网上。但是,我不太熟悉Python托管,这个应用程序使用Twisted和PyQT。我不知道如何在服务器上安装它们。我甚至不知道我所做的是否能在网上工作-你能在一个实时网站上使用Twisted或PyQT吗?我只对扭曲的行为有一种模糊的感觉。

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


Tags: 文件数据path方法图像jsonurlflask
1条回答
网友
1楼 · 发布于 2024-05-17 13:48:23

我假设您正在本地运行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)。在烧瓶中,您通常会键入:

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

…这就意味着。。。

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

如果你想,你可以直接输入这个网址。因此,javascript只需生成这个URL就可以工作了。

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

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

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

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

现在,具体的解决方案将取决于应用程序的需求。最直接的解决方案是使您想要显示的图像位于项目的/static目录中。

但是,如果您想创建一个Flask项目来处理硬盘上任何位置的文件(不需要首先有一个“上传”页面来选择文件),那么您可能选择了错误的工具(一个基于web的应用程序)来执行该任务。

相关问题 更多 >