@puromira

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

至急:お問い合わせフォームのエラーが解決できない

解決したいこと

お問い合わせフォームを作っているのですが内容がGmialに送れずエラーが出て、chatgptに質問しても解決しないため、こちらに質問しました。chatgptを使いながら作成したので、知識はあまりありません。

発生している問題・エラー

スクリーンショット 2025-03-19 185752.png

script.js↓↓

    // お問い合わせフォームの処理
    const contactForm = document.getElementById("contact-form");
    if (contactForm) {
        contactForm.addEventListener("submit", function (event) {
            event.preventDefault();

            const name = contactForm.querySelector("input[name='name']").value;
            const email = contactForm.querySelector("input[name='email']").value;
            const message = contactForm.querySelector("textarea[name='message']").value;

            fetch('/contact', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: new URLSearchParams({
                    'name': name,
                    'email': email,
                    'message': message
                })
            })
            
            .then(response => response.text())
            .then(data => {
                alert('お問い合わせを送信しました。');
                contactForm.reset();
            })
            .catch(error => {
                console.error('Error:', error);
                alert('お問い合わせの送信に失敗しました。');
            });
        });
    } else {
        console.error('Form element with id "contact-form" not found.');
    }

chatgptに質問したらserver.jsに問題があると出たので、貼っときます。

server.js↓↓

require('dotenv').config();
const express = require('express');
const nodemailer = require('nodemailer');
const bodyParser = require('body-parser');
const cors = require('cors'); 
const path = require('path');
const { sendMail } = require('./public/scripts');

const app = express();
const port = 3000; 

// Email configuration
const transporter = nodemailer.createTransport({
    service: 'gmail',
    auth: {
        user: '〇〇@gmail.com',
        pass: 'アプリパスワード入力済み'
    },
    debug: true,
    logger: true
});


// Serve static HTML files
app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, 'public', 'script.js'));
});

app.post('/contact', (req, res) => {
    const { name, email, message } = req.body;

    let mailOptions = {
        from: 'email', 
        to: '〇〇@gmail.com',
        subject: 'お問い合わせが来ました',
        text: `以下の内容でお問い合わせが来ました。\n\n【名前】: ${name}\n【メールアドレス】: ${email}\n【内容】: ${message}`
    };

    transporter.sendMail(mailOptions, (error, info) => {
        if (error) {
            console.log(error);
            return res.status(500).send('メール送信に失敗しました。');
        }
        res.send('お問い合わせを受け付けました。');
    });
});

分からないことがあれば教えてください!

0 likes

2Answer

const app = express(); の下に app.use(express.urlencoded()); と書けば直る気がします。

サーバーエラーであることは確かなので、これで直らなかったらサーバー側のエラーメッセージをログから探して貼ってください。

ちなみに、質問サイトで理由もなしに「至急」と書くのは無意味か逆効果なのでおすすめしません。自分勝手な奴と思われるだけです。本当に急ぐ理由があるなら説明すれば理解を得られるかもしれません。

1Like

Comments

  1. @puromira

    Questioner

    初心者だったので親切に「至急」は逆効果ということを教えてくださりありがとうございます。gmailのポートやenvを使ったりしてるのですがやはり、エラーが出てしまいます。
    スクリーンショット 2025-03-22 172401.png
    スクリーンショット 2025-03-22 172414.png
    スクリーンショット 2025-03-22 172431.png
    スクリーンショット 2025-03-22 172715.png

  2. 環境によっては出ることがあるエラーのようですね。 nodemailer の接続設定で回避できるかもしれません。

    server.js を動かしている環境はどこですか?手元のマシンなのか、 GCP などのクラウドなのかで設定が変わってきます。

  3. @puromira

    Questioner

    手元のマシンです。後、エラーの内容が変わりました。

    Failed to load resource: the server responded with a status of 500 (Internal Server Error)
    

    スクリーンショット 2025-03-22 185024.png

node.jsをローカルで動かされているのでしょうか?
そのテストをしているのでしょうか?
node.jsかもしれない、と前提をいれて、なぜ動かないかWindows copilotに聞いてみました。
node.jsを私は知らないのですが、copilotはthink deeperで私よりは的確な内容を答えていると思いますので、貼り付けてみます。


以下のコードは Node.js の Express を使っており、nodemailer によるメール送信機能が実装されています。つまり、Node.js 上で動作しており、メール送信自体はセットアップできれば正常に動くはずです。しかし、現状のコードで 500 エラーが発生している原因として、いくつか疑うべき点があります。

1.リクエストボディのパースがされていない
bodyParser はインポートされていますが、ミドルウェアとして 使用されていません。Express 4.16以降はビルトインの express.json() や express.urlencoded() を利用できるため、これらを追加する必要があります。
リクエストの POST ボディがパースされず、req.body が undefined になっていると、以下のようにデストラクチャリングする部分でエラーが発生します。

app.post('/contact', (req, res) => {
  const { name, email, message } = req.body;
  // もし req.body が undefined だったらここでエラー
  ...
});

対策:
ルーティングよりも前にミドルウェアを追加してください。

// もし JSON 形式で送信する場合
app.use(express.json());

// もしくはフォームの値を送るなら以下も
app.use(express.urlencoded({ extended: true }));

2.メール送信オプションの設定について
mailOptions from の フィールドが 'email' となっています。これは有効なメールアドレスではなく、nodemailer 側でエラーとなる可能性が高いです。通常は、送信元に有効なメールアドレスを指定する必要があります。
対策:
送信元には、自分のメールアドレスまたは送信用に設定したメールアドレスを指定してください。たとえば:

let mailOptions = {
    from: '〇〇@gmail.com', // 有効なメールアドレスに変更
    to: '〇〇@gmail.com',
    subject: 'お問い合わせが来ました',
    text: `以下の内容でお問い合わせが来ました。\n\n【名前】: ${name}\n【メールアドレス】: ${email}\n【内容】: ${message}`
};

3.Gmail 認証の確認

  • 認証情報:
    Gmail の場合、通常のパスワードではなく「アプリパスワード」などが必要です。すでにアプリパスワードを入力済みとのことですが、認証情報が正しいか、また Gmail 側で安全性の低いアプリのアクセスが許可されているか再確認してください。
  • セキュリティ設定:
    Gmail のアカウントの設定で「安全性の低いアプリのアクセス許可」や、「2段階認証」の設定状況が影響している可能性があります。

4.静的ファイルの配信について
現状、app.get('/') で返しているのは script.js です。本来 HTML ファイルを返したい場合は、ファイルパスを確認してください。また、静的ファイルが複数ある場合は以下のように設定すると便利です。

app.use(express.static(path.join(__dirname, 'public')));

これにより、 public フォルダ内の HTML、CSS、JS ファイルが適切に配信されるようになります。

まとめと次のステップ

  • Node.js としては問題なく動作するはずです。
  • 500 エラーの原因としては主にリクエストボディのパースと from の設定が疑われます。
  • 上記の修正を行った上で、再度エラーログを確認してください。nodemailer のログやデバッグ情報(debug:true,logger:true があるため)からさらに詳細なエラー原因がわかるはずです。

もしこれら修正してもまだエラーが発生する場合、エラー詳細とどのリクエストで発生しているのか(GET なのか POST なのか)を再度確認していただけると、さらに具体的な原因探しに繋がると思います。
また、テスト時に使用しているリクエストの Content-Type( application/json か application/x-www-form-unlencoded など)も合わせて確認すると良いでしょう。

1Like

Comments

  1. @puromira

    Questioner

    node.jsを使っています。
    gmailのポートやenvを使ったりしてるのですがやはり、エラーが出てしまいます。
    スクリーンショット 2025-03-22 172401.png
    スクリーンショット 2025-03-22 172414.png
    スクリーンショット 2025-03-22 172431.png
    スクリーンショット 2025-03-22 172715.png

    script.jsは変更なしです。
    server.jsは変更しているところがあります
    ###server

    require('dotenv').config();
    const express = require('express');
    const nodemailer = require('nodemailer');
    const bodyParser = require('body-parser');
    const app = express();
    app.use(express.urlencoded({ extended: true })); //  これが新しい書き方
    app.use(express.json()); //  JSONのデータも解析
    const cors = require('cors'); // cors を上に移動
    const path = require('path');
    app.use(express.static(path.join(__dirname, 'public')));
    
    app.get('/script.js', (req, res) => {
        res.type('application/javascript'); // 📌 MIMEタイプを明示的に指定
        res.sendFile(path.join(__dirname, 'public', 'script.js'));
    });
    
    //const { sendMail } = require('./public/script.js');
    
    
    const port = 3000; // ここに統一
    
    // Email configuration
    const transporter = nodemailer.createTransport({
        host: process.env.EMAIL_HOST,
        port: process.env.EMAIL_PORT,
        secure: false, // TLS を使用する場合は true に設定
        auth: {
          user: process.env.EMAIL_USER,
          pass: process.env.EMAIL_PASS,
        },
      });
    
    
    // Serve static HTML files
    app.get('/', (req, res) => {
        res.sendFile(path.join(__dirname, 'public', 'script.js'));
    });
    
    app.post('/contact', (req, res) => {
        const { name, email, message } = req.body;
    
        let mailOptions = {
            from: 'process.env.EMAIL_USER', 
            to: '入力済み',
            subject: 'お問い合わせが来ました',
            text: `以下の内容でお問い合わせが来ました。\n\n【名前】: ${name}\n【メールアドレス】: ${email}\n【内容】: ${message}`
        };
    
        transporter.sendMail(mailOptions, (error, info) => {
            if (error) {
                console.log(error);
                return res.status(500).send('メール送信に失敗しました。');
            }
            res.send('お問い合わせを受け付けました。');
        });
    });
    

    エラーの内容が変わりました。

    Failed to load resource: the server responded with a status of 500 (Internal Server Error)
    

    スクリーンショット 2025-03-22 185024.png

  2. すみませんが、最新のソースと、エラーを両方テキストで記載しただけないでしょうか

  3. ソースは、問い合わせを再編集で構いません

  4. @puromira

    Questioner

    再編集しました。

  5. 私はよくわからないので、Windows copilotに聞いてみました。
    単にWindows copilotに質問して、回答を貼っているだけですが、参考になることもあるかもしれません。


    エラー Error: self-signed certificate in certificate chain は、TLS の証明書検証の際に、自己署名証明書が使われているために発生します。つまり、接続先のメールサーバーが正式な認証局による証明書ではなく、自己署名証明書を返しているためです。この問題を解決するには、nodemailer の設定に TLS オプションを追加して証明書の検証をスキップする必要があります。

    解決方法 1: TLS 設定に rejectUnauthorized: false を追加
    注意:
    これは開発環境やテスト環境での一時的な回避策です。本番環境でのセキュリティリスクになるため、可能であれば正規の証明書を使用することが望ましいです。

    const transporter = nodemailer.createTransport({
      host: process.env.EMAIL_HOST,
      port: process.env.EMAIL_PORT,
      secure: false, // 例: ポート587では false、465なら true にする
      auth: {
        user: process.env.EMAIL_USER,
        pass: process.env.EMAIL_PASS,
      },
      tls: {
        // 自己署名証明書を許可
        rejectUnauthorized: false,
      },
    });
    

    解決方法 2: 環境変数の設定と利用方法の確認

    1. .env ファイルの内容例
      まず、 ファイルに正しい設定がされているか確認してください。たとえば Gmail を使う場合は以下のようになります:
    EMAIL_HOST=smtp.gmail.com
    EMAIL_PORT=587
    EMAIL_USER=あなたのメールアドレス@gmail.com
    EMAIL_PASS=アプリパスワード
    

    2.フィールドの設定
    現在のコードでは、from の値が文字列 'process.env.EMAIL_USER' になっています。これは環境変数ではなく、文字そのものになってしまいます。正しくは以下のように書く必要があります。

    let mailOptions = {
      from: process.env.EMAIL_USER,  // 環境変数を正しく参照
      to: '入力済みのメールアドレス',
      subject: 'お問い合わせが来ました',
      text: `以下の内容でお問い合わせが来ました。\n\n【名前】: ${name}\n【メールアドレス】: ${email}\n【内容】: ${message}`
    };
    

    補足: その他の確認事項

    • メールサーバーの設定:
      使用しているメールサーバー(例: Gmail)のセキュリティ設定や証明書状況を確認してください。Gmail であれば、通常上記の設定(host:'smtp.gmail.com'、port:587、secure:false)で利用できるはずですが、2段階認証やアプリパスワードの設定が正しいか確認しましょう。
    • サーバー起動ログ:
      変更後もエラーが出る場合は、nodemailer のデバッグオプション(debug:true,logger:true)を活用して、詳細なエラーメッセージを確認してください。

    以上の修正を行い、再度実行してみてください。もしこれでもまだエラーが解消されない場合、メールサービス側の証明書の問題か、あるいは環境変数の値が想定通りでない可能性があるため、再度設定を見直すことをおすすめします。
    また、メールサーバーによっては証明書チェーンの構成が異なるため、正式な環境で運用する際は、自己署名証明書を回避するための正しい証明書を利用するか、セキュリティ面を十分考慮した上での設定変更を行ってください。
    他にも、エラー発生時の送信リクエスト内容や通信ログの詳細、利用しているメールサーバーの仕様なども確認できると、さらに原因の特定につながるかもしれません。

Your answer might help someone💌