Laman statik tidak menjalankan kod sebelah pelayan, tetapi borang kenalan masih memerlukannya. Berikut adalah cara saya menghubungkan borang kenalan PHP/PHPMailer pada laman Hugo yang digunakan pada hosting dikongsi melalui SSH — dan apa yang tidak kena sepanjang perjalanan.
Persediaan
Laman ini dibina dengan Hugo dan outputnya di-rsync ke hos cPanel yang dikongsi. PHP tersedia di sebelah pelayan, jadi borang kenalan menghantar ke fail contact.php yang berada bersama output Hugo dalam public_html/.
PHPMailer mengendalikan penghantaran SMTP. Saya menyertakan perpustakaan secara terus (tanpa Composer) — fail-fail berada dalam static/vendor/phpmailer/ dan Hugo menyalinnya ke dalam public/ semasa pembinaan.
Memastikan Kelayakan Tidak Masuk Git
Kelayakan SMTP tidak seharusnya disimpan dalam git. Pendekatannya:
contact.phpmemanggilrequire __DIR__ . '/mail-config.php';mail-config.phpmentakrifkan pemalar (SMTP_HOST,SMTP_USER,SMTP_PASS, dll.)static/mail-config.phpditambah ke.gitignorestatic/mail-config.example.phpdisimpan dalam git sebagai templat rujukan
Di pelayan, mail-config.php mendapat chmod 600 — boleh dibaca oleh pemilik proses sahaja.
Deployment melalui SSH
Arahan deployment:
hugo && rsync -avz --exclude='mail-config.php' \
-e "ssh -p 7822" \
public/ user@ftp.example.com:~/public_html/ \
&& ssh -p 7822 user@ftp.example.com \
"chmod 600 ~/public_html/mail-config.php"
Perkara penting:
--exclude='mail-config.php'menghalang rsync daripada menimpa fail kelayakan yang hidupchmod 600digunakan semula selepas setiap deployment sebagai langkah keselamatan
Nyahpepijat SMTP
Kelayakan dalam mail-config.php pada mulanya salah. Untuk mendiagnosis, saya memuat naik skrip ujian yang menjalankan PHPMailer dengan SMTPDebug = 2 terus di pelayan:
scp -P 7822 smtp_test.php user@ftp.example.com:/tmp/
ssh -p 7822 user@ftp.example.com "php /tmp/smtp_test.php; rm /tmp/smtp_test.php"
Output debug menunjukkan 535 Incorrect authentication data dengan serta-merta — mengesahkan ia adalah masalah kelayakan, bukan tembok api atau isu TLS. Setelah diperbetulkan, output menunjukkan 235 Authentication succeeded dan mel berjaya dihantar.
Kebenaran Fail
Hosting dikongsi sangat ketat tentang kebenaran fail. Peraturannya:
| Jenis | Kebenaran |
|---|---|
| Direktori | 755 |
| Fail | 644 |
| Konfigurasi sensitif | 600 |
Hugo menyalin fail dari static/ dengan mengekalkan kebenaran sumbernya. Jika fail sumber mempunyai mod yang salah, ia akan menjadi salah di pelayan. Betulkan sekali di sumber:
find static -type f -exec chmod 644 {} \;
find static -type d -exec chmod 755 {} \;
Selepas itu, setiap pembinaan hugo menghasilkan output dengan kebenaran yang betul dan rsync menyebarkannya dengan bersih — tiada pembetulan kebenaran di sebelah pelayan diperlukan pada deployment masa hadapan.
Dua fail yang memerlukan perhatian manual:
.htaccessberada terus dalampublic_html/, tidak diuruskan oleh Hugo. Tetapkan sekali:chmod 644 .htaccess. Apache tidak dapat menyajikan sebarang halaman jika tidak dapat membaca fail ini.mail-config.phpdikecualikan dari rsync dan mestichmod 600— arahan deployment menguruskan ini.
Borang Kenalan: Fetch dan Bukannya POST Biasa
Borang asal menggunakan HTML biasa <form action="..."> POST. Ini berfungsi tetapi pelayar memaparkan JSON mentah di halaman apabila pengesahan gagal — pengguna melihat {"ok":false,"errors":[...]} dan perlu menekan Kembali.
Versi yang ditambah baik memintas penghantaran dengan fetch:
- Pengesahan sebelah klien berjalan dahulu — ralat jelas tidak pernah mencapai pelayan
- Ralat pelayan dipetakan kembali ke sorotan medan sebaris
- Apabila berjaya, JS mengubah hala ke
/{lang}/contact/?sent=1— halaman terima kasih yang betul
Satu perangkap dengan templat Hugo: penapis | jsonify membungkus nilai rentetan dalam tanda petikan JSON. Pada param seperti /contact.php ia menghasilkan "/contact.php" — betul. Tetapi digunakan dua kali ia menghasilkan "\"/contact.php\"", iaitu URL yang mengandungi aksara tanda petikan literal. Fetch gagal senyap-senyap. Gunakan interpolasi biasa sebaliknya:
var action = "{{ .Site.Params.contactFormAction }}";
Juga tambah ini_set('display_errors', '0'); di bahagian atas contact.php. Jika amaran PHP dihidupkan, ia akan ditambah ke hadapan badan respons JSON, merosakkan JSON.parse di pelayar.
Ringkasan
| Masalah | Penyelesaian |
|---|---|
| Kelayakan dalam git | mail-config.php berasingan, dalam gitignore, chmod 600 |
| Kegagalan pengesahan SMTP | Skrip ujian di pelayan dengan SMTPDebug = 2 |
| 403 pada semua halaman | .htaccess adalah 700 — tetapkan ke 644 |
| 403 pada imej | Fail sumber static/ ada kebenaran salah — betulkan di sumber |
| Ralat penghuraian JSON di pelayar | display_errors=1 membocorkan amaran PHP ke dalam badan respons |
| “Something went wrong” semasa hantar | ` |