POST遷移をやり直したときにiOSのsafariが固まる

PHPで制作中に気づいた。

フォームからPOST遷移で次のページに行ったあと、
そこでリロードしたり、もしくはさらに次のページから戻ってきた場合
「フォームの内容の再送信をするか?」と聞かれます。

再送で同じページが出てくるならそれで良いのですが、
場合によっては再送させたくないので、別ページにリダイレクトしたりする場合があります。

今回は「リロード時のみ別ページに転送したい」ということでやってみたんですが
iOSのsafariだと、「再送しますか?」の画面で固まって、それ以上の操作を受け付けませんでした。

form.php

<?php
session_start();
if($_SERVER['REQUEST_METHOD']=='POST'){
  if(isset($_SESSION['token'])){
    // トークンがあれば正常、トークンは削除
    echo 'success';
    session_destroy();
    exit;
  }else{
    // トークンがなければエラーページへリダイレクト
    header('Location: errer.html'); // デフォルトでは302でリダイレクト
    exit;
  }
}else{
  // 通常アクセスの際にトークンを発行
  $_SESSION['token']=1;
}
?>
<html><body>
<form action="" method="POST"><input type="submit" value="post"></form>
</body></html>

ところで、リダイレクトは
301 Moved Permanently
302 Moved Temporarily
の他にも
303 See Other
307 Temporary Redirect
というのがあるんですね。

本来ならPOSTして302リダイレクトが帰ってきたら、
リダイレクト先にもPOSTしないといけない(らしい)。

302の場合は
「POSTしましたけどー」「うちじゃないよ、転送先を当たってくれ」
なので、転送先にもあらためてPOSTすることを想定してる。

303の場合はPOST後にGETで見せたいなど、
「POSTしましたけどー」「処理は完了した、次にこっちを見てくれ」
という場合に使うんですね。

ブラウザのPOSTリクエストは、リダイレクトさせるとGETに化ける? ::ハブろぐ

なので、もしかしたら303でリダイレクトしてやったらsafariも固まらないのか?と思いまして

header("HTTP/1.1 303 See Other");
header('Location: error.html');
exit;

としてみましたが、やっぱりsafariは固まりました。

となると、本来であればPOST後のページをform.phpで出すのではなく、
その時点でリダイレクトするというPRGパターン(POST-Redirect-GET)にしておけば良いんでしょうね。
(戻って固まるのは同じだが、頻度は減る?)

あとはそもそもリダイレクトしないことだな。

古いWordPressサイトをStaticPressで静的に書き出してしまおう

WordPressで作ってた古いサイトを静的サイトに変換しておけば、
今後バージョンアップだとかセキュリティアップデートだとかに手間取らない。

ということで久々に触ったサイトのWordpressを最新版にバージョンアップして
StaticPressプラグインを導入。

有効化するぞーと思ったらエラーが。
class-static_press.phpの965行目でsyntax error。unexpected T_SL…

$regex = <<<'END'
/
(中略)
/x
END;

PHPのヒアドキュメントの開始でエラー。
シングルクォートで囲む ‘xxx’ という指定法はNowdoc形式といって、PHP5.3以降でないと使えない。
今回使ってたサーバーはさすが古いだけあって5.2.xでした。

幸い、(中略)の中にシングルクォートや変数を含む部分は無かったので

$regex = '
/
(中略)
/x
';

として解決。
直接プラグインを書き換えるのは一時しのぎだけど、
どうせこのサイトは静的に書き出してしまうのだからこれでも良かろう。

「良かろう」なんて普段使わない言葉遣いしたら亘理町の「よかろう寿司」に行きたくなったわね!はらこめし!
(↓元祖はらこめし味くらべのときの様子)

で、有効化したらメニューのStaticPressから設定して書き出し開始。
設定の「静的サイト URL」は、出力したファイルを後で運用するURLを指定しておく。
「出力先ディレクトリ (ドキュメントルート)」は既存のwordpressファイルととカブると面倒なので
独自のディレクトリを指定しておいた方がラクだと思う(無ければ作ってくれる)。

あとはできあがったファイルを適当に移設して公開すればオッケーよ!

更新しなくなったWordPressサイトを静的にしておく

WordPressはPHPで動的にサイトを出してます。
当然サーバーのCPUパワーを食うので、更新しなくなったサイトは静的に変換して置いておきたい。
StaticPress等のプラグインを入れて出力させるのが常套手段なのですが、現段階の最新版Wordpress4.7.2に入れたらエラーが出たりして(使っているテーマ、環境にもよると思います)。

ならば無理矢理クロールして取ってしまえ!ということでwget
$ wget -nc -x -r http://example.com

出来上がったファイルは拡張子がhtmlじゃないものも多いので、
設置先サーバーのほうでMIME-typeをいじります。

今回はnginx上に置いたので

server {
    server_name example.com;
    location / {
        default_type text/html;
    }
}


これだけ。
たぶんApacheでもDefaultType text/htmlとか書いておけば拡張子ナシでもhtmlとして出してくれるでしょう(未確認)

あとはアクセスしてみて、微妙にリンク先が無かったりするものは個別に手直し。
Wordpressに限らず動的サイトを静的にするのに使えるなぁ。

2017-04-19 追記: wgetによる収集では一部欠けているようで、
やはりなんとかアップデートした後にStaticPressするのが良さそうです。

WordPressサイトの全SSL化…一部リンクがSSLにならない

とあるwordpressを使ってるサイトを常時SSL化することになりました。
VPSだったのでSSL証明書の取得からインストールまでLet’s Encryptですんなり行きました。

Let’s Encrypt 総合ポータル

次にWordpressの設定でホームURLを http から https に変更します。
そして全文検索してhttpのリンクをhttpsにします。
このへんはSearch and Replace for WordPress Database Scriptを使用。

WordPress移行時にURLをSQLで直接一括置換はダメ! 「Search and Replace for WordPress Databases Script」を使おう | infoScoop開発者ブログ

あとはテーマのファイルをgrepしてhttp箇所を //からの表記に直したり…

しかしメニューのリンクとか一部プラグインの出力がSSLにならない。
ソースを見るとget_page_link()とかで呼んでるわけです。
じゃぁ中身の設定に従うはずだよなぁ…と wp-includes/link-templates.php を読み、
データベースを疑い…わからん。

しかし結局Really Simple SSLというプラグインを入れたらあっさり解決。
なんだ、どこにこの違いがあったのだ…

WordPressを一瞬でHTTPS化するプラグイン「Really Simple SSL」の使い方

今後常時SSLサイトが増えるだろうし、もうちょっと根本的に原因を探りたいのだがなぁ

CentOS6にFML8でメーリングリスト

いろいろコラボレーションツールとかありますが、根強い人気のメーリングリスト。
みんなが使い慣れたインターフェースで、スマホにも届くし、
新しいことを覚えなくていいので、使いたいご要望をよくいただきます。

しかしMLは使いたくてもMLの管理はみんなやりたがらない。
コマンドメール送ってねといってもやらない。
今回の目的は、メンバー全員に届く&返信も全員にできる、ぐらいですからね。

そんなわけで久々にCentOS6にFML8を導入しました。他はpostfixとapacheです。

■ポイント
・perlのモジュール揃える
・CGI動かすのに苦労、suexec配下なのとmod_perlじゃダメ

■インストール
本家の説明の通り。
この時点でアレが足りないとか言われたらyumでインストールする。

■バーチャルドメイン
makefml newdomain example.net するのを忘れない
virtual_alias_mapsの指定を忘れない

■管理用webインターフェース(CGI)を使う
SuEXECでfmlユーザーが動かないといけないのでそのようにする。
/home/fml/public_html/cgi-bin/以下略~となるので
http://example.com/~fml/cgi-bin/以下略~と動かす。
表向きのドメインにUserDirが見えるのもなんだかなーということでfmlだけ使えるようにする
続きを読む