質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.34%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

205閲覧

fetchからPythonで用意した関数を呼び出したい

Kurimeshi

総合スコア15

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

1グッド

1クリップ

投稿2025/01/15 09:19

編集2025/01/16 13:38

実現したいこと

webページのテキストボックスからjavascriptコードを受け取り,受け取ったコードの実行でエラーが出る場合はエラー名とエラー内容をデータベースに保存するというwebアプリケーションを作りたいです

発生している問題・分からないこと

明らかにエラーが発生するコードを入力してもPython側で用意したlog_error関数が呼び出されている気配がなく,またデバッグ用に記述したconsole.log("test1")などのメッセージがターミナル側で表示されません

エラーメッセージ

error

1特にエラーは発生しなかったのですが,ログはこんな感じでした 2 * Serving Flask app 'test' 3 * Debug mode: on 4WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. 5 * Running on http://127.0.0.1:5000 6Press CTRL+C to quit 7 * Restarting with stat 8 * Debugger is active! 9 * Debugger PIN: 119-491-145 10127.0.0.1 - - [15/Jan/2025 15:16:39] "POST /test_code HTTP/1.1" 405 - 11127.0.0.1 - - [15/Jan/2025 15:16:44] "GET / HTTP/1.1" 200 - 12127.0.0.1 - - [15/Jan/2025 15:16:48] "POST / HTTP/1.1" 302 - 13127.0.0.1 - - [15/Jan/2025 15:16:48] "GET /test_code HTTP/1.1" 200 -

該当のソースコード

test.py

1 2from flask import Flask, render_template, request, jsonify, session, redirect, url_for 3from flask_sqlalchemy import SQLAlchemy 4from datetime import datetime 5import json 6import os 7 8# test.py 9 10app = Flask(__name__) 11 12app.config["SECRET_KEY"] = os.urandom(24) 13base_dir = os.path.dirname(__file__) 14error_log = "sqlite:///" + os.path.join(base_dir, "error_log.sqlite") 15app.config["SQLALCHEMY_DATABASE_URI"] = error_log 16app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False 17 18from jinja2 import StrictUndefined 19app.jinja_env.undefined = StrictUndefined 20 21db = SQLAlchemy(app) 22 23class ErrorLog(db.Model): 24 id = db.Column(db.Integer, primary_key=True) 25 error_name = db.Column(db.String(100), nullable=False) 26 error_message = db.Column(db.Text, nullable=False) 27 source = db.Column(db.Text, nullable=True) 28 line_number = db.Column(db.Integer, nullable=True) 29 column_number = db.Column(db.Integer, nullable=True) 30 31 def __repr__(self): 32 return f"<ErrorLog('{self.error_name}', {self.error_message})>" 33 34@app.route("/", methods=["GET", "POST"]) 35def index(): 36 if request.method == "POST": 37 code = request.form.get("code") 38 session["code"] = code 39 print(code) 40 return render_template("view_test.html", code=code) 41 return render_template("view_test.html", code = "") 42 43# @app.route("/test_code", methods=["GET"]) 44# def test_code(): 45# code = session.get("code", "") 46# return render_template("view_test.html", code=code) 47 48@app.route('/log_error', methods=['POST']) 49def log_error(): 50 print("log_error") 51 try: 52 data = request.get_json() 53 error_name = data.get('error_name', 'Unknown Error') 54 error_message = data.get('error_message', '') 55 line_number = data.get('line_number', None) 56 column_number = data.get('column_number', None) 57 source = session.get("code", "") 58 59 new_error = ErrorLog( 60 error_name=error_name, 61 error_message=error_message, 62 source=source, 63 line_number=line_number, 64 column_number=column_number 65 ) 66 db.session.add(new_error) 67 db.session.commit() 68 69 return jsonify({"message": "Error logged successfully"}), 200 70 71 except Exception as e: 72 return jsonify({"message": f"Error logging failed: {str(e)}"}), 500 73 74if __name__ == "__main__": 75 with app.app_context(): 76 db.create_all() 77 app.run(debug=True) 78

view_test.html

1 2<!DOCTYPE html> 3<html lang="en"> 4<head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>Test JavaScript Execution</title> 8</head> 9<body> 10 <h1>JavaScript Execution Test</h1> 11 <form method="POST" enctype="multipart/form-data"> 12 <label for="code">JavaScript Code:</label><br> 13 <textarea id="code" name="code" rows="10" cols="50"></textarea><br> 14 <input type="submit" value="Execute"> 15 </form> 16 17 <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.2/p5.js"></script> 18 <script> 19 window.addEventListener('error', async function(event) { 20 const errorData = { 21 error_name: event.error ? event.error.name : 'Error', 22 error_message: event.error ? event.error.message : '', 23 line_number: event.lineno || null, 24 column_number: event.colno || null, 25 }; 26 27 await fetch('/log_error', { 28 method: 'POST', 29 headers: { 30 'Content-Type': 'application/json', 31 }, 32 body: JSON.stringify(errorData), 33 }); 34 console.log('Error logged successfully:', errorData); 35 }); 36 37 // エラーハンドリングを追加 38 try { 39 console.log("test1"); 40 const jsCode = `{{ code|safe }}`; 41 eval(jsCode); 42 } catch (error) { 43 console.log("test2") 44 console.error('Error executing code:', error); 45 } 46 </script> 47</body> 48</html>

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

最初はtry-catch文でエラーが発生しているかどうか調べていたのですが,window.addEventListenerでエラーを検知するよう変更してみたりしました

補足

実行OS: Mac OS Sequoia 15.1.1
コードの記述,実行はvscodeで行いました

tatsu99👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

問題点: テンプレートでの変数名 (js_code)、フォームでの名前 (js_code)、
Pythonコード上での変数名 (code)、セッションキーの名前 (code)がそれぞれ異なってます。

具体的に問題になるのは2箇所

  • フォームでの名前が js_code なのに、Python 上では form.get("code")
  • テンプレートでは js_code なのに render_template の引数では code

解決策: 上記2点の解消、もしくはキー及び変数の名称を統一する。


別問題ですが(Method Not Allowed になるので)
フォームから値を読みだしてセッションに格納しているのは index() です。
/test_code でも同じフォームが表示されますが、その画面で送信しても
form の action 指定がないので現在のページ (/test_code) 宛てに送信されます。
methods が POST なのでエラーになりますが、
ここをGET許可してもフォームの値は得られない点には留意してください。
(デバッグでいろいろ試してる場合を想定)


追記

後者のテンプレート内の未定義変数に関しては、jinja2 テンプレートの設定で検出可能です。

python

1from jinja2 import StrictUndefined 2app.jinja_env.undefined = StrictUndefined # TODO: 実際には、デバッグ時のみ有効にする。

追記2 eval周りのtry/catch を外す ⇒ throw で外部へエラーを伝搬

内側のtry/catch に例外が捕捉され、
外部のaddEventListenerで登録したエラーハンドラに伝搬していない。

diff

1 2 try { 3 console.log("test1"); 4 const jsCode = `{{ code|safe }}`; 5 eval(jsCode); 6 } catch (error) { 7 console.log("test2") 8 console.error('Error executing code:', error); 9+ throw error; 10 } 11

投稿2025/01/16 04:46

編集2025/01/16 16:57
teamikl

総合スコア8791

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Kurimeshi

2025/01/16 05:43 編集

回答ありがとうございます 追記していただいたjinjaテンプレート設定でコードを実行したところ、リクエストメソッドがgetだった際にcodeをview_text.htmlに渡すのを忘れていたことがわかったため一応修正を行いました しかしご指摘いただいたように変数名をcodeで統一してみましたが、変更後もエラーログデータベースの更新は行われませんでした また、エラーハンドリングの部分でコンソールにログを表示するようにしたのですが、少なくともコードを実行しているターミナルではログが表示されませんでした これはそもそもエラーハンドリング自体が実行されていないのではと思ったのですがどうなのでしょうか
teamikl

2025/01/16 07:02

期待する fetch が発生しないのは、 eval に対しての try/catch がエラーを捕捉してる為かな。 現状のコードから変更する場合 ⇒ try/catch を外し例外を外側に伝搬。もしくは catch 内で fetch のコード呼び出し > 少なくともコードを実行しているターミナルではログが表示されませんでした エラーハンドリング自体は chrome/win で確認出来てます。 まずは、読み込んだ HTMLのソースを表示して 期待した jsCode が得られているかどうかを確認しましょう。 空になってる場合は、エラーは起こりません。 ちなみにテストケース `; alert("OK"); ` ⇒ エラーは起こらない。  evalの外でコードが実行されてしまう。jsCode は空文字。 1/0 ⇒ JavaScript ではエラーにならない。
Kurimeshi

2025/01/16 13:45

ご指摘を受けた通りtry/catch文を外して実行しなおしたところ、htmlソースで入力したコードがちゃんと表示されることが確認できました とりあえず一歩前進できたみたいなのですが、log_errorの呼び出し、およびデータベースの更新はできていませんでした
teamikl

2025/01/16 15:29 編集

log_error 呼び出し~データベース更新まで確認できてます。 他にどこかで齟齬があるかな?もしくは確認方法 > try/catch文を外して実行しなおしたところ、htmlソースで入力したコードがちゃんと表示されることが確認できました eval 周りの try/catch を外す事と、 htmlソースで入力したコードが表示されるには関連がありません。 try/catch を外すと例外が外側に伝わり addEventHandler で登録した処理 fetch /log_error が呼ばれるはずです。
Kurimeshi

2025/01/16 15:38

申し訳ありません try-catch文を外す場所を間違えていたみたいで,eval周りのtry-catchを外したところ無事log_errorが呼ばれデータベースが更新されていることを確認できました 夜遅くまでお付き合いいただき本当にありがとうございました
Kurimeshi

2025/01/16 16:20

解決後に聞くのもあれですが質問が一つあります ここでは書いていなかったのですが,質問を投稿する前は入力されたコードをevalを使わずそのままコード内に入れ込んで実行を行っていました その時のコードのままご指摘をいただいた部分だけ修正して実行してみたところ,再度エラーの検出が行われなくなったのですがこれはなぜでしょうか 当方javascriptの経験がほぼなく,もしかしたらとんだ愚問だったりするかもしれませんが,もしよろしければこちらも回答いただけるとありがたいです
teamikl

2025/01/16 17:04

予想されるのは、エラー自体が起こってないか、 エラーが外側に伝わってない可能性ですね。 window.addEventListener で登録したエラーハンドラは 例外が何処にも捕捉されなかった場合に呼び出されます。 try/catch が例外を捕捉する為、 明示的に throw しないと外側のエラーハンドラで検出できません。 ※ try/catch よりも throw での解決の方が良いと思ったので、回答を修正。 もしくは、windowのエラーハンドラで検出でなくても、 catch の所で fetch ~のコード呼び出しでも良いはずです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.34%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問