首页 > 解决方案 > 如何适当地提供与烧瓶集成的静态 js 文件?

问题描述

我目前正在通过 EDX 使用 Python 和 Javascript 进行 Web 编程。具体来说,我使用的是 Socket.IO。我遇到了一个错误,我不太确定如何修复,想知道​​是否有人可以提供帮助。这是课程本身的源代码。

文件结构:

-venv
     -static
            -index.js
     -templates
            -index.html
     -application.py

这是应用程序.py:

import os

from flask import Flask, jsonify, render_template, request
from flask_socketio import SocketIO, emit

app = Flask(__name__)
app.config["SECRET_KEY"] = os.getenv("SECRET_KEY")
socketio = SocketIO(app)

votes = {"yes": 0, "no": 0, "maybe": 0}


@app.route("/")
def index():
    return render_template("index.html", votes=votes)


@socketio.on("submit vote")
def vote(data):
    selection = data["selection"]
    votes[selection] += 1
    emit("vote totals", votes, broadcast=True)

这是 index.js:

document.addEventListener('DOMContentLoaded', () => {

    // Connect to websocket
    var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port);

    // When connected, configure buttons
    socket.on('connect', () => {

        // Each button should emit a "submit vote" event
        document.querySelectorAll('button').forEach(button => {
            button.onclick = () => {
                const selection = button.dataset.vote;
                socket.emit('submit vote', {'selection': selection});
            };
        });
    });

    // When a new vote is announced, add to the unordered list
    socket.on('vote totals', data => {
        document.querySelector('#yes').innerHTML = data.yes;
        document.querySelector('#no').innerHTML = data.no;
        document.querySelector('#maybe').innerHTML = data.maybe;
    });
});

这是 index.html:

<html>

<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js">
    </script>
    <script type="text/javascript" src="{{url_for('static', filename='index.js')}}"></script>
    <title>Vote</title>
</head>

<body>
    <div>Yes Votes: <span id="yes">{{ votes["yes"] }}</span></div>
    <div>No Votes: <span id="no">{{ votes["no"] }}</span></div>
    <div>Maybe Votes: <span id="maybe">{{ votes["maybe"] }}<span></div>
        <hr>
        <button data-vote="yes">Yes</button>
        <button data-vote="no">No</button>
        <button data-vote="maybe">Maybe</button>      
    </body>

</html>

我遇到的问题是应用程序无法正常工作。只有当我直接将 js 直接插入 HTML 文件时,它才会起作用。由于某种原因,将其用作静态文件不起作用。当我尝试将其作为静态文件提供时,我确实有一个控制台错误,指出“未捕获的 TypeError:无法设置属性 'onclick' of null”。我假设问题是在脚本运行时没有加载内容,但是在 html 页面上移动脚本似乎没有做任何事情。有什么建议吗?

谢谢你。

标签: javascriptpythonflask

解决方案


解决这个问题的方法是在文件夹中插入index.js一个js文件static夹,并将脚本移动到正文的底部。

最终的 HTML 代码:

<!DOCTYPE html>
<html>

<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js">
    </script>
    <title>Vote</title>
</head>

<body>
    <div>Yes Votes: <span id="yes">{{ votes["yes"] }}</span></div>
    <div>No Votes: <span id="no">{{ votes["no"] }}</span></div>
    <div>Maybe Votes: <span id="maybe">{{ votes["maybe"] }}<span></div>
        <hr>
        <button data-vote="yes" id="yesvote">Yes</button>
        <button data-vote="no" id="novote">No</button>
        <button data-vote="maybe" id="maybevote">Maybe</button>  
        <script type="text/javascript" src="{{url_for('static', filename='js/index.js')}}"></script>    
    </body>

</html>

推荐阅读