简介
配置gitbook项目,显示浏览记数,结果报错:
Access to XMLHttpRequest at 'https://hitcounter.pythonanywhere.com/count?url=http%253A%252F%252F192.16.7.162%253A51122%252Fscript_docs%252FDB2_dbhealthcheck.html%253Fq%253D' from origin 'http://192.16.7.162:51122' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
原因是 网站跨域请求禁止了,所以,我们可以使用Flask框架来实现一个简单的页面访问计数器功能,步骤如下:
步骤:
创建一个Flask应用: 使用Flask框架编写一个Python脚本,用于处理请求并返回页面访问次数。
存储页面访问次数: 可以使用内存中的字典或者数据库来根据请求的URL存储和增加访问次数。
部署Flask应用: 完成后,你可以将这个Flask应用部署到本地服务器或云服务器上。
数据存储在内存
安装python依赖包:
1 pip3 install flask flask-cors
新增app.py
程序:
1from flask import Flask, request, jsonify
2from flask_cors import CORS
3
4app = Flask(__name__)
5CORS(app) # 允许所有跨域请求
6
7# 存储页面访问次数的字典
8page_views = {}
9
10@app.route('/count', methods=['GET'])
11def count():
12 # 获取请求的URL
13 target_url = request.args.get('url')
14
15 if not target_url:
16 return jsonify("缺少URL参数"), 400
17
18 # 增加页面访问次数
19 if target_url in page_views:
20 page_views[target_url] += 1
21 else:
22 page_views[target_url] = 1
23
24 # 返回当前访问次数
25 return jsonify(page_views[target_url])
26
27if __name__ == '__main__':
28 app.run(host='0.0.0.0', port=5000)
如何使用
将该脚本保存为
app.py
。运行该脚本来启动Flask服务:
python3 app.py
。在你的GitBook脚本中,将请求的URL更改为你服务器的IP或域名。
这样,每次用户访问GitBook页面时,都会向Flask服务器发送请求,并返回相应的页面访问次数。
测试代码:
1curl http://192.16.7.162:5000/count?url=htttps://www.dbaup.com
可以返回阅读记数。
1[root@alldb ~]# curl http://192.16.7.162:5000/count?url=htttps://www.baidu.com
21
3[root@alldb ~]# curl http://192.16.7.162:5000/count?url=htttps://www.baidu.com
42
5[root@alldb ~]# curl http://192.16.7.162:5000/count?url=htttps://www.dbaup.com
61
7[root@alldb ~]# curl http://192.16.7.162:5000/count?url=htttps://www.dbaup.com
82
9[root@alldb ~]# curl http://192.16.7.162:5000/count?url=htttps://www.dbaup.com
103
11[root@alldb ~]#
数据存储在磁盘文件中
为了使页面访问次数能够持久化,当Flask程序重启时不会丢失计数数据,可以将数据存储到磁盘文件中,例如使用JSON文件来存储页面访问次数。这样,程序每次启动时都会从文件加载数据,并在每次请求后更新文件。
1import json
2from flask import Flask, request, jsonify
3from flask_cors import CORS
4import os
5
6app = Flask(__name__)
7CORS(app)
8
9# 持久化文件路径
10DATA_FILE = 'page_views.json'
11
12# 加载页面访问次数
13def load_data():
14 if os.path.exists(DATA_FILE):
15 with open(DATA_FILE, 'r') as f:
16 return json.load(f)
17 return {}
18
19# 保存页面访问次数
20def save_data(data):
21 with open(DATA_FILE, 'w') as f:
22 json.dump(data, f)
23
24# 加载现有的访问次数
25page_views = load_data()
26
27@app.route('/count', methods=['GET'])
28def count():
29 # 获取请求的URL
30 target_url = request.args.get('url')
31
32 if not target_url:
33 return jsonify("缺少URL参数"), 400
34
35 # 增加页面访问次数
36 if target_url in page_views:
37 page_views[target_url] += 1
38 else:
39 page_views[target_url] = 1
40
41 # 将数据保存到文件
42 save_data(page_views)
43
44 # 返回当前访问次数
45 return jsonify(page_views[target_url])
46
47if __name__ == '__main__':
48 app.run(host='0.0.0.0', port=5000)
解释:
`load_data()`:程序启动时,从指定的JSON文件中加载页面访问次数。如果文件不存在,则返回一个空字典。
`save_data()`:每次请求后,将更新的页面访问次数写入到JSON文件中,确保数据持久化到磁盘。
`page_views`:程序启动时,从JSON文件中读取已有的数据。
使用说明:
当你启动Flask应用时,它会从
page_views.json
文件中加载数据。每次有新访问时,数据都会自动写回该文件。
即使重启Flask应用,页面访问次数也不会丢失。
只允许特定域名
1import json
2from urllib.parse import urlparse, unquote
3from flask import Flask, request, jsonify
4from flask_cors import CORS
5import os
6
7app = Flask(__name__)
8CORS(app)
9
10# 持久化文件路径
11DATA_FILE = 'page_views.json'
12
13# 加载页面访问次数
14def load_data():
15 if os.path.exists(DATA_FILE):
16 with open(DATA_FILE, 'r') as f:
17 return json.load(f)
18 return {}
19
20# 保存页面访问次数
21def save_data(data):
22 with open(DATA_FILE, 'w') as f:
23 json.dump(data, f)
24
25# 加载现有的访问次数
26page_views = load_data()
27
28# 检查URL是否包含 'dbaup.com' 作为主域名或子域名
29def is_dbaup_domain(url):
30 decoded_url = unquote(url) # 首先对URL进行解码
31 parsed_url = urlparse(decoded_url) # 解析URL
32 domain = parsed_url.netloc # 获取主域名
33 # 检查主域名是否包含 'dbaup.com'
34 return domain.endswith('dbaup.com')
35
36@app.route('/count', methods=['GET'])
37def count():
38 # 获取请求的URL
39 target_url = request.args.get('url')
40
41 if not target_url:
42 return jsonify("缺少URL参数"), 400
43
44 # 检查URL是否以 'dbaup.com' 作为主域名或子域名
45 if not is_dbaup_domain(target_url):
46 return jsonify("Disallowed Domains"), 403
47
48 # 增加页面访问次数
49 if target_url in page_views:
50 page_views[target_url] += 1
51 else:
52 page_views[target_url] = 1
53
54 # 将数据保存到文件
55 save_data(page_views)
56
57 # 返回当前访问次数
58 return jsonify(page_views[target_url])
59
60if __name__ == '__main__':
61 app.run(host='0.0.0.0', port=5000)
关键修改点:
`unquote(url)`:使用
urllib.parse.unquote()
对传入的URL进行解码,将类似https%253A%252F%252Fdbhealthcheck.dbaup.com%252Fscript_docs%252FDB2_dbhealthcheck.html
这样的编码URL转换为标准的https://dbhealthcheck.dbaup.com/script_docs/DB2_dbhealthcheck.html
。`parsed_url.netloc`:解析解码后的URL,并从中提取出主域名。
运行后的效果:
程序会先对URL进行解码,然后再检查是否符合
dbaup.com
主域名的要求。这样即使URL被编码,也能够正确地识别出
dbaup.com
域名并进行访问次数的计数。
脚本
修改文件_book/gitbook/gitbook-plugin-pageview-count/plugin.js
中的https://hitcounter.pythonanywhere.com/count
为你自己的服务器地址:
1function requestCount(targetUrl) {
2 return $.ajax('https://hitcounter.pythonanywhere.com/count',{
3 data:{url:encodeURIComponent(targetUrl)},
4 })
5}
为:
1function requestCount(targetUrl) {
2 return $.ajax('http://192.16.7.162:5000/count',{
3 data:{url:encodeURIComponent(targetUrl)},
4 })
5}
报错
Access to XMLHttpRequest at 'http://192.16.7.162:5000/count?url=http%253A%252F%252F192.16.7.162%253A51122%252Fscript_docs%252FDB2_dbhealthcheck.html' from origin 'http://192.16.7.162:51122' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
这个错误是因为浏览器的同源策略阻止了来自不同源的请求(CORS跨域请求)。为了解决这个问题,你需要在Flask服务器上允许跨域请求。
可以通过使用Flask的flask-cors
扩展来解决CORS问题。
效果
总结
1、可以使用宝塔面板将该程序部署为python程序,直接对外访问:https://hitcounter.dbaup.com/count
参考
https://blog.csdn.net/qq_21336651/article/details/100150264
https://developer.aliyun.com/article/1116353