使用 html.A 破折号下载文件,但文件显示 html

dash download file using html.A, but file shows html instead

我正在尝试使用以下代码在 Dash 中下载动态生成的 json 文件和 html.A 元素:

download_json_link = html.A(
    'Download JSON',
    id='download-json',
    download='download.json',
    href='',
    target="_blank",
)

dir_path = os.path.dirname(__file__)
filepath_json = "/downloads/barcode.json"
filename_json = dir_path + filepath_json
f = open(filename_json, "a")
f.write(str_json)
f.close()

@app.server.route('/downloads/<path:path>')
def serve_static(path):
    root_dir = os.getcwd()
    return flask.send_from_directory(
        os.path.join(root_dir, 'downloads'), path
    )

它正确生成 json 文件并将其保存到下载文件夹。但是,当我按下 html.A 元素时,下载的文件是这样的一堆 html,而不是生成的 json 文件:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Quantum Design</title>
        <link rel="icon" type="image/x-icon" href="/_favicon.ico?v=1.18.1">
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="stylesheet" href="https://codepen.io/chriddyp/pen/bWLwgP.css#">
    </head>
    <body>
        
<div id="react-entry-point">
    <div class="_dash-loading">
        Loading...
    </div>
</div>

        <footer>
            <script id="_dash-config" type="application/json">{"url_base_pathname": null, "requests_pathname_prefix": "/", "ui": true, "props_check": true, "show_undo_redo": false, "suppress_callback_exceptions": true, "update_title": "Updating...", "hot_reload": {"interval": 3000, "max_retry": 8}}</script>
            <script src="/_dash-component-suites/dash_renderer/polyfill@7.v1_8_3m1604000066.8.7.min.js"></script>
<script src="/_dash-component-suites/dash_renderer/react@16.v1_8_3m1604000066.14.0.js"></script>
<script src="/_dash-component-suites/dash_renderer/react-dom@16.v1_8_3m1604000066.14.0.js"></script>
<script src="/_dash-component-suites/dash_renderer/prop-types@15.v1_8_3m1604000066.7.2.js"></script>
<script src="/_dash-component-suites/dash_table/bundle.v4_11_1m1607375125.js"></script>
<script src="/_dash-component-suites/dash_html_components/dash_html_components.v1_1_1m1599150811.min.js"></script>
<script src="/_dash-component-suites/dash_core_components/dash_core_components.v1_14_1m1607542327.min.js"></script>
<script src="/_dash-component-suites/dash_core_components/dash_core_components-shared.v1_14_1m1607534701.js"></script>
<script src="/_dash-component-suites/dash_bootstrap_components/_components/dash_bootstrap_components.v0_12_0m1619764337.min.js"></script>
<script src="/_dash-component-suites/dash_renderer/dash_renderer.v1_8_3m1604000088.dev.js"></script>
            <script id="_dash-renderer" type="application/javascript">var renderer = new DashRenderer();</script>
        </footer>
    </body>
</html>

有人知道问题出在哪里吗?

您可以指定数据类型需要 json 并传入 json 数据的序列化版本,如下所示:

from dash import Dash
import dash_html_components as html
import os
import json

dir_path = os.path.dirname(__file__)
filepath_json = "/downloads/barcode.json"
filename_json = dir_path + filepath_json

with open(filename_json, encoding="utf-8") as f:
    data = json.load(f)
    data_string = json.dumps(data)

app = Dash(__name__)
app.layout = html.Div(
    html.A(
        "Download Data",
        id="download-link",
        download="download.json",
        href=f"data:text/json;charset=utf-8,{data_string}",
        target="_blank",
    )
)

if __name__ == "__main__":
    app.run_server()

https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs

https://napuzba.com/data-url/

看起来当我更新 href 时,我需要使用这样的相对路径:“/downloads/barcode.json”,而不是绝对路径。