首页 > 编程问答 >为什么我的 Flask 网站不断刷新?

为什么我的 Flask 网站不断刷新?

时间:2024-08-01 07:22:05浏览次数:14  
标签:javascript python flask

我正在尝试制作一个社交媒体网站(类似于 TikTok),但观看页面不断刷新。

我的 JS 将这样的 JSON 发送到后端,后端在 SQLite 中跟踪喜欢、不喜欢、视图等数据库:

{
  "action": {action e.g. like, dislike, view}
  "id": {video_id e.g. 1)
}

然后,后端使用此函数处理它:

@app.route('/trackStatistics-Ue3ARmqbiF63KepjbxeI', methods=['POST'])
def track_statistics():
    try:
        # Get the JSON data from the request
        data = request.get_json()

        # Validate the action and id
        if 'action' not in data or 'id' not in data:
            return jsonify({'error': 'Invalid request'}), 400

        action = data['action']
        video_id = data['id']

        data = get_video(video_id)

        print(data)

        if action == "like":
            data["likes"] = int(data["likes"]) + 1
        elif action == "dislike":
            data["dislikes"] = int(data["dislikes"]) + 1
        elif action == "unlike":
            data["likes"] = int(data["likes"]) - 1
        elif action == "undislike":
            data["dislikes"] = int(data["dislikes"]) - 1
        elif action == "view":
            data["views"] = int(data["views"]) + 1
        
        update_video(video_id, data["publisher"], data["title"], data["likes"], data["dislikes"], data["views"], data["comments"], False)

        print(data)

        # Return the updated data
        return jsonify(data)

    except Exception as e:
        print(str(e))
        return jsonify({'error': str(e)}), 500

这是定义了我的 update_video get_video create_video 函数的文件:

import sqlite3
import json
from datetime import datetime

def get_video(video_id):
    conn = sqlite3.connect('../databases/videos.db')
    c = conn.cursor()
    c.execute("SELECT * FROM videos WHERE id = ?", (video_id,))
    video = c.fetchone()
    comments = json.loads(video[6]) if video[6] else []
    video = list(video)
    video[6] = comments
    conn.close()
    return {
        "id": video[0],
        "publisher": video[1],
        "title": video[2],
        "likes": video[3],
        "dislikes": video[4],
        "views": video[5],
        "comments": video[6],
        "created_at": video[7],
        "updated_at": video[8]
    }

def create_video(publisher, title, likes, dislikes, views, comments):
    conn = sqlite3.connect('../databases/videos.db')
    c = conn.cursor()
    now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    comments_json = json.dumps(comments)
    c.execute("INSERT INTO videos (publisher, title, likes, dislikes, views, comments, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", 
              (publisher, title, likes, dislikes, views, comments_json, now, now))
    conn.commit()
    conn.close()
    return c.lastrowid

def update_video(video_id, publisher, title, likes, dislikes, views, comments, update_time):
    conn = sqlite3.connect('../databases/videos.db')
    c = conn.cursor()

    # Get the current updated_at time
    c.execute("SELECT updated_at FROM videos WHERE id = ?", (video_id,))
    last_updated = c.fetchone()[0]

    if update_time:
        now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    else:
        now = last_updated

    comments_json = json.dumps(comments)
    c.execute("UPDATE videos SET publisher = ?, title = ?, likes = ?, dislikes = ?, views = ?, comments = ?, updated_at = ? WHERE id = ?",
              (publisher, title, likes, dislikes, views, comments_json, now, video_id))
    conn.commit()
    conn.close()

    return json.dumps(get_video(video_id))

我试图跟踪视频统计信息服务器似乎工作正常,它打印了正确的数据!但是,在代码 200 成功后,它会刷新页面。

这是我用来与后端交互的 JS:

var liked = false;
var disliked = false;
var followed = false;
var commentsOpen = false;
var url = window.location.search;
var urlParams = new URLSearchParams(url);
var id = urlParams.get("c");

var trackStatisticsRoute =
    "http://localhost:5005/trackStatistics-Ue3ARmqbiF63KepjbxeI";

$(document).ready(function () {
    if (id) {
        document.title = "ByteClips - " + id;
    }

    var vidFile = "../videos/" + id + "/video.mp4";
    var dataFile = "../videos/" + id + "/data.json";

    console.log(vidFile);
    $("#vidSrc").attr("src", vidFile);
    $(".video")[0].load();

    fetch(dataFile)
        .then((response) => response.text())
        .then((data) => {
            data.id = id;
            vidData = JSON.parse(data);
        });

    console.log("updateRating view");
    updateRating("view", id);

    $(".video-buttons div button").on("mouseenter", function () {
        $(this).find("i").css("opacity", 0);
        $(this).find(".counter").css("opacity", 1);
    });

    $(".video-buttons div button").on("mouseleave", function () {
        $(this).find("i").css("opacity", 1);
        $(this).find(".counter").css("opacity", 0);
    });
});

function updateRating(action, id) {
    const requestData = {
        action: action,
        id: id,
    };

    $.ajax({
        type: "POST",
        url: trackStatisticsRoute,
        data: JSON.stringify(requestData),
        contentType: "application/json",
        success: function (data) {
            // console.log('AJAX request successful', data);
            // updateUI(data);
        },
        error: function (jqXHR, textStatus, errorThrown) {
            // console.log('AJAX request error:', textStatus, errorThrown);
            // console.log('Response:', jqXHR.responseText);
            // alert('AJAX request failed. Check console for details.');
            console.log("womp womp");
        },
    });
}

function updateUI(data) {
    let newData;
    if (typeof data === "string" || data instanceof String) {
        newData = JSON.parse(data);
    } else {
        newData = data;
    }
    $("#like .counter").text(data["likes"]);
    $("#dislike .counter").text(data["dislikes"]);
    $("#share .counter").text(data["views"]);
    $("#comment .counter").text(data["comments"].length);
}

if (liked) {
    $("#like").css("background", "#fff");
    $("#like").css("color", "#26daa5");
} else {
    $("#like").css("background", "#26daa5");
    $("#like").css("color", "#fff");
}
if (disliked) {
    $("#dislike").css("background", "#fff");
    $("#dislike").css("color", "#26daa5");
} else {
    $("#dislike").css("background", "#26daa5");
    $("#dislike").css("color", "#fff");
}
if (followed) {
    $("#follow").css("background", "#fff");
    $("#follow").css("color", "#26daa5");
    $("#follow i").attr("class", "fa-solid fa-user-minus");
} else {
    $("#follow").css("background", "#26daa5");
    $("#follow").css("color", "#fff");
    $("#follow i").attr("class", "fa-solid fa-user-plus");
}

$("#like").on("click", function () {
    if (liked) {
        // ons.notification.toast('Removed Like!', { timeout: 1000, animation: 'fall' });
        liked = false;
        $("#like").css("background", "#26daa5");
        $("#like").css("color", "#fff");
        console.log("updateRating unlike");
        updateRating("unlike", id);
    } else {
        // ons.notification.toast('Liked!', { timeout: 1000, animation: 'fall' });
        if (disliked) {
            console.log("updateRating undislike");
            updateRating("undislike", id);
        }
        liked = true;
        disliked = false;
        $("#like").css("background", "#fff");
        $("#like").css("color", "#26daa5");
        $("#dislike").css("background", "#26daa5");
        $("#dislike").css("color", "#fff");
        console.log("updateRating like");
        updateRating("like", id);
    }
});

$("#dislike").on("click", function () {
    if (disliked) {
        // ons.notification.toast('Removed Dislike!', { timeout: 1000, animation: 'fall' });
        disliked = false;
        $("#dislike").css("background", "#26daa5");
        $("#dislike").css("color", "#fff");
        console.log("updateRating undislike");
        updateRating("undislike", id);
    } else {
        // ons.notification.toast('Disliked!', { timeout: 1000, animation: 'fall' });
        if (liked) {
            console.log("updateRating unlike");
            updateRating("unlike", id);
        }
        disliked = true;
        liked = false;
        $("#dislike").css("background", "#fff");
        $("#dislike").css("color", "#26daa5");
        $("#like").css("background", "#26daa5");
        $("#like").css("color", "#fff");
        console.log("updateRating dislike");
        updateRating("dislike", id);
    }
});

$("#follow").on("click", function () {
    if (followed) {
        // ons.notification.toast('Unfollowed!', { timeout: 1000, animation: 'fall' });
        followed = false;
        $("#follow i").attr("class", "fa-solid fa-user-plus");
        $("#follow").css("background", "#26daa5");
        $("#follow").css("color", "#fff");
    } else {
        // ons.notification.toast('Followed!', { timeout: 1000, animation: 'fall' });
        followed = true;
        $("#follow i").attr("class", "fa-solid fa-user-minus");
        $("#follow").css("background", "#fff");
        $("#follow").css("color", "#26daa5");
    }
});

$("#comment").on("click", function () {
    console.log("comments opened");
    if (commentsOpen) {
        commentsOpen = false;
        $("#comment").css("background", "#26daa5");
        $("#comment").css("color", "#fff");
    } else {
        commentsOpen = true;
        $("#comment").css("background", "#fff");
        $("#comment").css("color", "#26daa5");
    }
});

我打开 Fiddler Classic 来调试请求和响应,这里有一些信息:|| |请求: POST http://localhost:5005/trackStatistics HTTP/1.1 主机:本地主机:5005 连接:保持活动状态 内容长度:26 sec-ch-ua:“不是)A;品牌”;v =“99”,“Microsoft Edge”;v =“127”,“Chromium”;v =“127” 接受:

/ sec-ch-ua-平台:“Windows” sec-ch-ua-移动: ?0 用户代理:{我对此进行了审查} 内容类型:application/json 来源: http://127.0.0.1:5500 Sec-Fetch-Site:跨站 秒获取模式:cors Sec-Fetch-Dest:空 引用地址: http://127.0.0.1:5500/ 接受编码:gzip、deflate、br、zstd 接受语言:en-US,en;q=0.9 {"action":"view","id":"1"}

响应: HTTP/1.1 200 好 服务器:Werkzeug/3.0.3 Python/3.12.4 日期:2024 年 7 月 31 日星期三 16:51:01 GMT 内容类型:application/json 内容长度:200 访问控制允许来源:

http://127.0.0.1:5500 变化:来源 连接:关闭 { “评论”: ”[]”, "创建时间": "2024-07-30 23:30:05", “不喜欢”:0, “id”:1, “喜欢”:0, “出版商”:“1”, "title": "测试1", “更新时间”:“2024-07-31 05:23:12”, “浏览量”:108 }

是的,我使用 MS Edge,因为我没有足够的存储空间来安装任何其他浏览器,并且您无法卸载 Edge ._.

我不太了解如何重现此问题,但我'我想我正在尝试在 Flask 后端使用 sqlite3 写入 SQL 文件。我在这个问题中给出了整个页面的所有代码,因为我很愚蠢。

这是一个可重现的示例(相信我,我尝试通过将 CSS 和 JS 放入 HTML 中来使其简短,哈哈):

create一个文件夹 在该文件夹中,再创建 3 个名为

src scripts 的文件夹。 现在,当您仍在包含 databases src scripts 的根文件夹中时,创建一个名为requirements.txt 的txt 文件并将以下文本放入其中: databases 现在,进入 src/ 文件夹然后在 watch.html 中创建一个名为

flask
flask-cors

. watch.html 的文件,复制并粘贴

中的代码(字符限制让我明白了) https://pastebin.com/raw/Q1EGGEu0 然后,返回到包含

脚本的根文件夹``` 文件夹。 src`` folder and enter the 在该文件夹中创建一个名为

的新文件,然后复制并粘贴此代码: watch.py 最后,在与

from flask import Flask, request, jsonify
from flask_cors import CORS
import sqlite3
import json
from datetime import datetime

app = Flask(__name__)
CORS(app)

def get_video(video_id):
    conn = sqlite3.connect('../databases/videos.db')
    c = conn.cursor()
    c.execute("SELECT * FROM videos WHERE id = ?", (video_id,))
    video = c.fetchone()
    comments = json.loads(video[6]) if video[6] else []
    video = list(video)
    video[6] = comments
    conn.close()
    return {
        "id": video[0],
        "publisher": video[1],
        "title": video[2],
        "likes": video[3],
        "dislikes": video[4],
        "views": video[5],
        "comments": video[6],
        "created_at": video[7],
        "updated_at": video[8]
    }

def create_video(publisher, title, likes, dislikes, views, comments):
    conn = sqlite3.connect('../databases/videos.db')
    c = conn.cursor()
    now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    comments_json = json.dumps(comments)
    c.execute("INSERT INTO videos (publisher, title, likes, dislikes, views, comments, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", 
              (publisher, title, likes, dislikes, views, comments_json, now, now))
    conn.commit()
    conn.close()
    return c.lastrowid

def update_video(video_id, publisher, title, likes, dislikes, views, comments, update_time):
    conn = sqlite3.connect('../databases/videos.db')
    c = conn.cursor()

    # Get the current updated_at time
    c.execute("SELECT updated_at FROM videos WHERE id = ?", (video_id,))
    last_updated = c.fetchone()[0]

    if update_time:
        now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    else:
        now = last_updated

    comments_json = json.dumps(comments)
    c.execute("UPDATE videos SET publisher = ?, title = ?, likes = ?, dislikes = ?, views = ?, comments = ?, updated_at = ? WHERE id = ?",
              (publisher, title, likes, dislikes, views, comments_json, now, video_id))
    conn.commit()
    conn.close()

    return json.dumps(get_video(video_id))

@app.route('/trackStatistics-Ue3ARmqbiF63KepjbxeI', methods=['POST'])
def track_statistics():
    try:
        # Get the JSON data from the request
        data = request.get_json()

        # Validate the action and id
        if 'action' not in data or 'id' not in data:
            return jsonify({'error': 'Invalid request'}), 400

        action = data['action']
        video_id = data['id']

        data = get_video(video_id)

        print(data)

        if action == "like":
            data["likes"] = int(data["likes"]) + 1
        elif action == "dislike":
            data["dislikes"] = int(data["dislikes"]) + 1
        elif action == "unlike":
            data["likes"] = int(data["likes"]) - 1
        elif action == "undislike":
            data["dislikes"] = int(data["dislikes"]) - 1
        elif action == "view":
            data["views"] = int(data["views"]) + 1
        
        update_video(video_id, data["publisher"], data["title"], data["likes"], data["dislikes"], data["views"], data["comments"], False)

        print(data)

        # Return the updated data
        return jsonify(data)

    except Exception as e:
        print(str(e))
        return jsonify({'error': str(e)}), 500

if __name__ == '__main__':
    app.run(debug=True, use_debugger=True, port=5005)

包含此代码的同一文件夹中创建另一个名为 setup.py 的文件: watch.py 在包含

import json
from datetime import datetime
import sqlite3

def create_video(publisher, title, likes, dislikes, views, comments):
    conn = sqlite3.connect('../databases/videos.db')
    c = conn.cursor()
    now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    comments_json = json.dumps(comments)
    c.execute("INSERT INTO videos (publisher, title, likes, dislikes, views, comments, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", 
              (publisher, title, likes, dislikes, views, comments_json, now, now))
    conn.commit()
    conn.close()
    return c.lastrowid

# Connect to the SQLite database
conn = sqlite3.connect('../databases/videos.db')
c = conn.cursor()

# Create the videos table
c.execute('''CREATE TABLE IF NOT EXISTS videos
             (id INTEGER PRIMARY KEY,
              publisher TEXT,
              title TEXT,
              likes INTEGER,
              dislikes INTEGER,
              views INTEGER,
              comments TEXT,
              created_at TEXT,
              updated_at TEXT)''')

conn.commit()
conn.close()

create_video(1, "test video FOR TESTING", 0, 0, 0, [""])

和其他文件夹的根文件夹中打开命令提示符/终端,并创建 venv.txt 文件。激活 venv 并输入: src 然后:

pip install -r requirements.txt

运行

cd scripts

使用此命令: setup.py 然后,运行

python setup.py

使用另一个命令: watch.py 现在,您应该有一个在 127.0.0.1 运行的本地服务器。 0.1:5005。

python watch.py

我使用 VSCode 的扩展来执行下一步。 最后,打开 example/src/watch.html,其中 example 是您的根文件夹名称,将其托管在端口 5500 上。编辑 url 以在最后添加 ?c=1 。

从那里,您应该能够看看发生了什么。谢谢你! Live Server extension for VSCode to do this next step. finally, open example/src/watch.html where example is your root folder name, hosting it locally on port 5500. edit the url to include ?c=1 at the very end.

from there, you should be able to see what is happening. thank you!


页面不断刷新的原因是正在使用 AJAX 请求更新视频统计信息,并且在成功更新后,的 AJAX 成功处理程序没有明确指示浏览器不要执行任何其他操作。默认情况下,当不阻止默认操作时,提交表单(即使通过 AJAX)会导致页面刷新。

可以在 AJAX 成功处理程序中添加 event.preventDefault(); 来解决此问题。

但是,目前的代码中没有表单提交。页面刷新可能是由另一个元素或脚本触发的。因为没有包含加载视频和触发 AJAX 请求的 HTML 代码,所以我只能推测可能是什么原因造成的。

以下是可能导致刷新的其他一些原因以及如何解决这些问题的步骤:

  1. 按钮位于表单内: 确保的“喜欢”、“不喜欢”等按钮不在 <form> 标记内。如果是,则单击它们可能会触发表单提交并刷新页面。要解决此问题,请将按钮移出表单,或将按钮类型明确设置为“button”: html <button type="button">点赞</button>

  2. 页面上的其他 JavaScript 代码: 检查页面上的其他 JavaScript 代码,特别是任何与视频播放器或与这些按钮交互的事件监听器。某些代码可能会在更新后重新加载视频或刷新页面。

  3. 浏览器缓存: 在某些情况下,浏览器缓存可能会导致意外行为。尝试清除浏览器缓存或硬刷新页面(Ctrl+Shift+R 或 Cmd+Shift+R),看看是否能解决问题。

调试技巧:

  • 使用浏览器开发工具: 大多数现代浏览器都有内置的开发工具(在 Chrome 中按 F12 访问),可以在其中检查“网络”选项卡以查看是否正在发出任何意外请求或刷新页面。
  • 使用 console.log() 在的 JavaScript 代码的各个点添加 console.log() 语句,以跟踪执行流程并查看任何意外行为。

通过仔细检查的代码并使用这些调试技巧,应该能够确定刷新页面的原因并解决问题。

标签:javascript,python,flask
From: 78816031

相关文章