from flask import Flask, request, jsonify, make_response, render_template_string, send_from_directory import random import string import json app = Flask(__name__, static_folder='dist') def generate_random_id(): chars = string.ascii_lowercase + string.digits return ''.join(random.choices(chars, k=5)) # --- CORSヘッダーを全レスポンスに追加 --- @app.after_request def add_cors_headers(response): origin = request.headers.get('Origin') if origin: response.headers['Access-Control-Allow-Origin'] = origin response.headers['Access-Control-Allow-Credentials'] = 'true' response.headers['Access-Control-Allow-Headers'] = 'Content-Type' return response @app.route('/') def index(): id_list = request.cookies.get('ids') ids = json.loads(id_list) if id_list else [] html = ''' IDリスト

IDリスト

/eruda.js

getid のデータ

ここにデータが表示されます
''' return render_template_string(html, ids=ids) @app.route("/load.js") def load_js(): js_code = """ (async () => { const script = document.currentScript; if (!script) { console.error('currentScriptが取得できませんでした。'); return; } const debugMode = script.getAttribute('debug') === 'alert'; const activeValue = script.getAttribute('active'); if (!activeValue) { console.log('active属性が見つかりません。処理を終了します。'); return; } const ids = activeValue.trim().split(/\\s+/).filter(id => /^[a-zA-Z0-9]{5}$/.test(id)); if (ids.length === 0) { console.warn('active属性に5桁の番号または文字列が見つかりません。処理を終了します。'); return; } try { const url = 'https://soiz1-eruda3.hf.space/getid'; const res = await fetch(url, { method: 'GET', credentials: 'include' }); if (!res.ok) { const msg = `Fetchエラー: ステータス ${res.status} ${res.statusText}`; console.error(msg); if (debugMode) alert(msg); return; } const data = await res.json(); console.log('fetchレスポンス:', data); if (debugMode) alert(`fetchレスポンス:\\n${JSON.stringify(data)}`); if (!Array.isArray(data)) { const msg = 'fetchレスポンスが配列ではありません。認証失敗とみなします。'; console.error(msg); if (debugMode) alert(msg); return; } const hasAuthorized = ids.some(id => data.includes(id)); if (hasAuthorized) { const msg = '認証成功: 対象IDがfetchレスポンスに含まれています。runeruda()を実行します。'; console.log(msg); if (debugMode) alert(msg); runeruda(); } else { const msg = '認証失敗: 対象IDがfetchレスポンスに含まれていません。'; console.warn(msg); if (debugMode) alert(msg); } } catch (err) { const msg = `例外発生: ${err.message}`; console.error(msg, err); if (debugMode) alert(msg); } })(); """ return Response(js_code, mimetype='application/javascript') @app.route('/add', methods=['POST']) def add_id(): id_list = request.cookies.get('ids') ids = json.loads(id_list) if id_list else [] new_id = generate_random_id() ids.append(new_id) resp = make_response('', 303) resp.headers['Location'] = '/' resp.set_cookie( 'ids', json.dumps(ids), samesite='None', # ← クロスオリジンには必要 secure=True # ← 'None' にすると secure も必要 ) return resp @app.route('/delete', methods=['POST']) def delete_id(): id_to_delete = request.form.get('id') id_list = request.cookies.get('ids') ids = json.loads(id_list) if id_list else [] if id_to_delete in ids: ids.remove(id_to_delete) resp = make_response('', 303) resp.headers['Location'] = '/' resp.set_cookie( 'ids', json.dumps(ids), samesite='None', # ← クロスオリジンには必要 secure=True # ← 'None' にすると secure も必要 ) return resp @app.route('/getid') def get_ids(): id_list = request.cookies.get('ids') ids = json.loads(id_list) if id_list else [] return jsonify(ids) @app.route('/service-worker.js') def service_worker(): response = make_response(send_from_directory('.', 'service-worker.js')) response.headers['Content-Type'] = 'application/javascript' return response @app.route('/') def serve_static(filename): return send_from_directory(app.static_folder, filename) if __name__ == '__main__': app.run(host='0.0.0.0', port=7860, debug=True)