MTOS管理画面のSSL化:TinyMCE上で、http://からの絶対パスでURLが記載される問題を修正する
はじめに
ただ単に管理画面をSSL化するだけでは、編集画面にて画像が呼び出された際に、http://から始まるURLで呼ばれてしまい、クロスオリジンによるブラウザの警告が出てきてしまいます。
なお、このクロスオリジンの警告が出るのは、次の場合です。
- 編集画面に遷移した後、保存していた本文がエディタの編集領域に読み込まれた際
- エディタのツールボタンの画像挿入ボタンを押して、画像選択のダイアログが出た状態にて、MTに登録済みの画像のサムネイルを表示する際
- エディタのツールボタンから、画像のhtmlソースを挿入する際
今回は、この各操作時にクロスオリジンの警告が出ないよう、カスタマイズを行います。
ウェブページ/記事の編集画面が読み込まれた際に、サイト内コンテンツへのURL記載をルート相対に変換する
[MT本体のルートディレクトリ]/tmpl/cms/edit_entry.tmpl の 673行目あたり、
name="text" および name="text_more" となっている textarea が、
ウェブページ/ブログ記事編集画面が呼び出された場合に出力される、本文/続きの内容であるようです。
<mt:unless name="editors">
<mt:if name="rich_editor"><mt:var name="rich_editor_tmpl"><mt:else><mt:include name="include/archetype_editor.tmpl"></mt:if>
<mt:else>
<mt:include name="include/editor_script.tmpl" id="editor_script_include">
<mt:setvarblock name="editor_content">
<textarea id="editor-input-content" class="text" name="text" style="display: none"><$mt:var name="text" escape="html"$></textarea>
<textarea id="editor-input-extended" class="text" name="text_more" style="display: none"><$mt:var name="text_more" escape="html"$></textarea>
</mt:setvarblock>
</mt:unless>
この内、mt:setvarblock name="editor_content" の配下を次のように変更します。
書き換えたコードを[MT本体ルートディレクトリ]/alt-tmpl/cms/edit_entry.tmpl として配置します。
<mt:setVarBlock name="var_abs2rel">/https?:\/\/[ドメイン名]/g</mt:setVarBlock>
<mt:setvarblock name="editor_content">
<textarea id="editor-input-content" class="text" name="text" style="display: none"><$mt:var name="text" escape="html" regex_replace="$var_abs2rel","" $></textarea>
<textarea id="editor-input-extended" class="text" name="text_more" style="display: none"><$mt:var name="text_more" escape="html" regex_replace="$var_abs2rel","" $></textarea>
</mt:setvarblock>
これで、ウェブページ/記事の編集画面に遷移した際、サイト内コンテンツへのURL記載がルート相対化されました。
エディタのツールボタン「画像挿入」を押してポップアップする画像選択のダイアログにて、画像のサムネイルのURLをルート相対にする
次の画像の通り、ツールボタン「画像挿入」押下で表示される画像選択のダイアログでは、
画像を選択すると画像のサムネイルが表示されます。
このサムネイルはimgタグによるものですが、src属性に指定されたURLは絶対パスになっています。
これが、クロスオリジンの警告の原因となっています。
具体的にどのような仕組みで本事象の発生に至っているか、コードを追ってみます。
まず、ダイアログのアイテムリストを生成しているのは、[MT本体のルートディレクトリ]/tmpl/cms/dialog/asset_list.tmpl です。
このテンプレートの139行目あたりを見ると、JSによりサムネイルの生成が行われているように見えます。
<mt:if name="has_thumbnail">
<a href="javascript:void(0)" onclick="return toggleAssetDetails('<mt:var name="id" escape="js">');" title="<$mt:var name="file_name" escape="html"$>"><$mt:var name="label" escape="html"$></a>
<div id="asset-<mt:var name="id" escape="html">-preview" class="asset-preview"></div>
<mt:else>
<mt:var name="label" escape="html">
</mt:if>
具体的には、次のJSの関数によって画像サムネイルのソースが生成をおこなっているようです。
onclick="return toggleAssetDetails('<mt:var name="id" escape="js">');"
toggleAssetDetails() が定義されているのは、次のjsファイル。
/mt-static/js/assetdetail.js
このファイルの中身を見てみると、直接的に問題のサムネイルのソースを生成しているのは、showPage() だと分かります。
function showPage(id) {
(中略)
if (asset.preview_url) {
preview = "<div class=\"asset-preview-image picture small\"><img src=\"" + asset.preview_url + "\" class=\"preview\" /></div>";
} else {
これを次のように修正する事で、画像のURLのルート相対化を行います。
if (asset.preview_url) {
//>>変更ここから
var rootrel_preview_url = asset.preview_url.replace( /https?:\/\/[^\/]+/g, "" );
preview = "<div class=\"asset-preview-image picture small\"><img src=\"" + rootrel_preview_url + "\" class=\"preview\" /></div>";
//<<変更ここまで
} else {
しかし、これだけだと、クロスオリジンの警告は消えません。
更に assetdatail.js をよく見ると、displayAssetDetails() の定義内の、108行目あたりの処理でサムネイル画像が読み込まれている事が分かります。
if (asset.thumbnail_url) {
guardian = 0;
thumb = new Image;
thumb.src = asset.thumbnail_url;
これを次のように変更します。
if (asset.thumbnail_url) {
guardian = 0;
thumb = new Image;
thumb.src = asset.thumbnail_url.replace( /https?:\/\/[^\/]+/g, "" );
これで、クロスオリジンの警告が消えました。
エディタのツールボタンから画像のhtmlソースを本文/続きに挿入する際、画像のURLをルート相対化する
例えば、dummy.png という画像を、エディタのツールボタン「画像挿入」から挿入すると、
本文内には、例えば次のようなhtmlソースが、エディタ内のカーソル位置に挿入されます。
※なお、画像挿入の際のダイアログでの設定内容によって、挿入されるhtmlソースの内容は若干異なります。
<a href="http://www.km92.net/knowledge/images/dummy.png"><img alt="dummy.png" src="http://www.km92.net/knowledge/assets_c/2014/06/dummy-thumb-400xauto-48.png" width="400" height="302" class="mt-image-none" style="" /></a>
しかし、見て分かる通り、ソース内のURLは絶対パスであり、ウィジウィグエディタでクロスオリジンの警告が出てしまいます。
これを修正します。
修正対象は、asset_insert.tmpl の冒頭、name="upload_html" が画像/アイテム挿入時に本文/続き内に挿入されるhtmlコードです。
<mt:include name="dialog/header.tmpl">
<mt:setvarblock name="insert_script" id="insert_script">
window.parent.app.insertHTML( '<mt:var name="upload_html" escape="js">', '<mt:var name="edit_field" escape="js">' );
</mt:setvarblock>
<script type="text/javascript">
/* <![CDATA[ */
// do the following first... asset manager stuff is ONLY for edit entry
<mt:if name="upload_html">
<mt:var name="insert_script">
</mt:if>
この内、<mt:setvarblock name="insert_script" id="insert_script"> の辺りを次のように書き換えます。
書き換えたコードを[MT本体ルートディレクトリ]/alt-tmpl/cms/edit_entry.tmpl として配置します。
JSのコードでURLをルート相対化しているのは、MTタグで上手く除去できなかったからです(x_x)。
<mt:setVarBlock name="var_abs2rel">/https?:\/\/(www\.|)km92.net/g</mt:setVarBlock>
<mt:setvarblock name="insert_script" id="insert_script">
var regx_ptn = /https?...[a-zA-Z0-9\._\-~]+/g;
rootrel_upload_html = '<mt:var name="upload_html" escape="js" regex_replace="$var_abs2rel","" />';
window.parent.app.insertHTML( rootrel_upload_html.replace(regx_ptn,""), '<mt:var name="edit_field" escape="js">' );
</mt:setvarblock>
※上述冒頭で、変数var_abs2relに設定している正規表現文字列「(www\.|)km92.net」は、お使いの環境のドメインがマッチするように変更して下さい。
これで、先の例と同一の手順で画像挿入をやっても、ソース内のURLは次のようにルート相対となります。
<a href="/knowledge/images/dummy.png"><img alt="dummy.png" src="/knowledge/assets_c/2014/06/dummy-thumb-400xauto-48.png" width="400" height="302" class="mt-image-none" style="" /></a>
あとがき
今回の対応で少し注意したい所は、エディタのツールボタン「画像挿入」押下で出てくるダイアログ内の画像選択のサムネイルの部分です。
imgタグのsrc属性のURLだけでなく、JSのImageオブジェクトのsrc属性に設定される画像のURLも考慮せねばならない、と言うところです。
参考
とほほのWWW入門
http://www.tohoho-web.com/www.htm
HTMLImageElement - Web API インターフェイス | MDN
https://developer.mozilla.org/ja/docs/Web/API/HTMLImageElement
About MDN by Mozilla Contributors is licensed under CC-BY-SA 2.5.