2014年6月16日 星期一

Drupal 的簡潔網址 (含 NAT port forwarding 環境下的設定方式)

Drupal 的 「Clean URL」 (簡潔網址) 功能, 就是利用 apache2 的 rewrite 模組, 讓原本長得像是 http://localhost/d7/?q=node/1 之類的醜醜連結變成比較清爽的連結: http://localhost/d7/node/1 。 已經玩 Drupal 一陣子了, 也燒毀過不少網站 ^_^||| 照理來說已經累積一些經驗了, 但每次設定 clean URL 卻還是經常卡住。 網路上已經有很多英文版的簡潔網址教學文, 例如 Getting Started: Clean URLs 以及 Clean URLs with Apache 2 on Ubuntu 等等。 運氣好的話, 照做就成功了。 但運氣不好的時候, 最苦惱的就是連錯在哪裡都看不出來。 這次花我最多時間而且搜尋不到解決方法的, 是一個棘手的問題: 如何替 「藏在 NAT port forwarding 後面」 的 drupal 設定 clean URL? 不論你在設定 clean URL 的時候遇到什麼樣的問題, 最重要的就是要挖出更多的線索與錯誤訊息, 以便明確地找到失敗的主因。 本文的分解動作有點囉嗦, 但希望能夠幫助那些沒有頭緒的人達到上述目標。

首先, 在初始化 drupal 的時候, 請不要啟動 clean URL。 例如我都沒有用網頁介面, 而是下 drush 指令來初始化 drupal: drush site-install standard --site-name='絕地學苑' --clean-url=0 --account-pass='站長的秘密' --db-url=mysql://root:資料庫密碼@localhost/drupal7

如果是已經架好的站 (比方說用 drush archive-restore 還原回來的網站), 可以先用 drush vset clean_url 0 暫時取消簡潔網址。

其次, 要確認你的 drupal 根目錄 (比方說是 /var/www/d7 好了) 裡面的 .htaccess 有被 apache2 看見。 先在 .htaccess 裡面找到 RewriteBase / 那一句。 (一開始可能被註解掉了。 先不管它。) 在這一句下面亂打一列垃圾, 例如 asfhioaccx7f。 在瀏覽器裡面重新整理 (/d7) 網頁。 如果 apache2 有看到你的 .htaccess , 那麼這時應該出現 internal server error 之類的錯誤訊息。 反過來說, 如果你看到的依舊是正常的 drupal 網頁, 那就表示 apache2 根本沒看到你的 .htaccess。 於是你需要確認三件事:

  1. 在 /etc/apache2/conf.d 裡面建一個文字檔, 檔名隨便 (比方叫做 drupal7 好了) 檔案內容是:
        <Directory "/var/www/d7"> # 記得要改成你的 drupal 根目錄
             AllowOverride All
        </Directory>
    
  2. 檢查 /etc/apache2/sites-available/default (或者, 如果你啟用 https 的話, 就要檢查 default-ssl) 裡面, 確認 apache2 的主設定檔的 <Directory "/var/www/d7"> ... </Directory> 那一節裡面 不應該出現 「AllowOverride None」 這一句話。 如果有的話, 請用 # 把它註解掉。
  3. 檢查 apache2ctl -M 印出的資料當中, 是否包含一句 rewrite_module 之類的? 如果沒有的話, 請下 a2enmod rewrite 啟動 rewrite 模組。

以上的修改不會立即生效, 要等你下了 service apache2 restart 之後才會生效。

再重新整理網頁, 看到 internal server error 了嗎? 恭喜! 在 /var/log/apache2/error.log 這個檔案的最尾巴, 你會看到 apache2 抱怨看不懂 .htaccess 裡面的那句垃圾。 現在把那句垃圾刪掉、 把 RewriteBase 那一句的註解 (井號) 拿掉、 把它修改成正確的路徑。 以本文的例子來說, 要改成: RewriteBase /d7 。 修改 .htaccess 之後, 並不需要重新啟動 apache2。 可以在瀏覽器裡重新整網頁, "internal server error" 不見了, 一切又恢復正常。

接下來可以用 drush vset clean_url 1 指令啟動 clean URL。

或是從瀏覽器裡登入 admin, 在 configuration 選單底下找到 Clean URLs 並點進去。 如果你看到有一個 「Enable clean URLs」 等著你勾選, 應該就成功了。 勾選並按 「save configuration」。 回到首頁, 把滑鼠移到某篇文章的連結上面, 原先內含 "?q=" 的網址, 現在已經不含這三個字元了!

但如果在 configuration 底下的 Clean URLs 頁面看到的是 「Clean URLs cannot be enabled」、 「Run the clean URL test」 之類的訊息, 那就只好繼續往下看了。 根據 這個留言, 你可以編輯 /etc/apache2/apache2.conf 並在最後面加上兩句:

    RewriteLog "/var/log/apache2/rewrite.log"
    RewriteLogLevel 3

重新啟動 apache2 之後, 可以下 tail -f /var/log/apache2/rewrite.log 追蹤查看 rewrite 模組到底如何改寫網址。 我自己看了半天看不懂, 跟先前其他正常的 drupal7 網站的紀錄檔看來也沒什麼不同。

然後突然想到會不會是 port forwarding 的關係? 最近在玩 proxmox, 開了很多虛擬主機, 但實體 IP 不夠用, 所以設了 NAT (Network Address Translation)。 我在使用這部 (沒有對外 IP 的) 虛擬主機時, 其實是採用類似這樣的網址: http://163.17.9.256:12345/d7/ 搜尋很久, 找不到談論如何替 「藏在 NAT 後面」 的 drupal7 設定 clean URL。 於是我用 ssh 登入這部 (沒有對外 IP 的) 虛擬主機。 在這裡下 w3m http://localhost/d7 用文字瀏覽器登入 admin 帳號並來到 configuration 選單底下的 Clean URLs 連結, 點進去看... 果然看到有一個 「Enable clean URLs」 等著我勾選! 然後就一路順暢設定成功了! 當然你也可以用 ssh -X ... 登入, 並執行 iceweasel 或 chromium , 用圖形瀏覽器來設定。

順便公告一下: 我的 drupal 新手筆記 已經從 fedora 改成 debian, 並且改採 「不要用 debian 內建的版本, 而是用 drupal 官網的最新版」 的方式架站。

沒有留言:

張貼留言