我正在尝试制作一个社交媒体网站(类似于 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 代码,所以我只能推测可能是什么原因造成的。
以下是可能导致刷新的其他一些原因以及如何解决这些问题的步骤:
-
按钮位于表单内: 确保的“喜欢”、“不喜欢”等按钮不在
<form>
标记内。如果是,则单击它们可能会触发表单提交并刷新页面。要解决此问题,请将按钮移出表单,或将按钮类型明确设置为“button”:html <button type="button">点赞</button>
-
页面上的其他 JavaScript 代码: 检查页面上的其他 JavaScript 代码,特别是任何与视频播放器或与这些按钮交互的事件监听器。某些代码可能会在更新后重新加载视频或刷新页面。
-
浏览器缓存: 在某些情况下,浏览器缓存可能会导致意外行为。尝试清除浏览器缓存或硬刷新页面(Ctrl+Shift+R 或 Cmd+Shift+R),看看是否能解决问题。
调试技巧:
- 使用浏览器开发工具: 大多数现代浏览器都有内置的开发工具(在 Chrome 中按 F12 访问),可以在其中检查“网络”选项卡以查看是否正在发出任何意外请求或刷新页面。
-
使用
console.log()
: 在的 JavaScript 代码的各个点添加console.log()
语句,以跟踪执行流程并查看任何意外行为。
通过仔细检查的代码并使用这些调试技巧,应该能够确定刷新页面的原因并解决问题。
标签:javascript,python,flask From: 78816031