IIS URL Rewrite の Outbound Rules で CSS の中身を書き換える
例えば、以下のように CSS の中にある URL を、IIS の URL Rewrite で書き換えたい場合の話です。
例:
body { padding-top: 50px; padding-bottom: 223px; background-image: url(/content/images/abc.png); background-image: url(/content/images/abc.png); }
以下のように、URL 「/content」ではなく、「/replacedcontents19」に置き換えたい:
body { padding-top: 50px; padding-bottom: 223px; background-image: url(/replacedcontents19/images/abc.png); background-image: url(/replacedcontents19/images/abc.png); }
Web.config の設定
以下のように設定します。
<rewrite> <outboundRules> <rule name="RewriteCSS" preCondition="ResponseIsCss"> <match filterByTags="None" pattern="/content/([^"\)]*)" /> <action type="Rewrite" value="/replacedcontents19/{R:1}" /> </rule> <preConditions> <preCondition name="ResponseIsCss"> <add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/css" /> </preCondition> </preConditions> </outboundRules> </rewrite>
CSSの場合は、filterByTags="None"
と設定する必要があります。HTMLの場合は、URL Rewrite Module 2.0 Configuration Reference : The Official Microsoft IIS Site ここの「Pre-defined tags」を参照し、適切な値を設定します。
filterByTags="None"を設定した場合、コンテンツ全体を走査し置き換えたい箇所を特定しているので、負担がかかります。
ですので、対処として「rewriteBeforeCache」や「occurrences」の設定が用意されています(先のページを参照)。今回はそれは使用していません。
違う例
先ほどは、正規表現を、/content/([^"\)]*)
と指定しています。
例えば、もしこの正規表現を、/content/(.*)
とした場合、1行に複数個所該当する場合は、正しく置き換えられません。
以下のような CSS だと、
body { padding-top: 50px; padding-bottom: 223px; background-image: url(/content/images/abc.png); background-image: url(/content/images/abc.png); } .div1 { background-image: url(/content/images/abc.png); }
次のように、最初と最後のurlだけがマッチされて、置き換えられます。
中盤の行末にある url は置き換えられません。
body { padding-top: 50px; padding-bottom: 223px; background-image: url(/replacedcontents19/images/abc.png); background-image: url(/content/images/abc.png); } .div1 { background-image: url(/replacedcontents19/images/abc.png); }
正規表現(.*)が、行の最後までマッチしてしまっていることが原因だと思いますが、
正規表現がまるで”行ごと”に置き換えているような挙動の理由が、分からないままです。(=なぜ、3つめのurlは置換されているのか?)
→追記:正規表現において「.」は、改行コード以外の1文字を表すためだと思われます。
環境
環境は、IIS 10 と URL Rewrite Module 2.0 で試しました。
試したコードをこちらに置いておきます。test.css · GitHub
参考サイト
- url rewriting - how do I know what version of IIS7 URL Rewrite module is installed - Stack Overflow
- iis 7 - How to fix URL Rewriting for links inside CSS files with IIS7 - Stack Overflow
- url rewriting - Does IIS / ARR rewrites one URL per line ONLY? - Stack Overflow
- URL Rewrite Module 2.0 Configuration Reference : The Official Microsoft IIS Site
おまけ検証追加
検証1
CSSのセミコロンを無しで、同じ行に2回登場させてみる。
置き換える値を固定値にしてみる。
正規表現は(.*)。
Web.config:
<outboundRules> <rule name="RewriteCSS" preCondition="ResponseIsCss"> <match filterByTags="None" pattern="/content/(.*)" /> <action type="Rewrite" value="replaced1" /> </rule>
元のCSS:
body { padding-top: 50px; padding-bottom: 223px; background-image: url(/content/images/abc.png) url(/content/images/abc.png); } .div1 { background-image: url("/content/images/abc.png"); } .div6 { background-image: url(/content/images/content/abc.png); } .div7 { background-image: url("/content/images/content/abc.png"); }
結果、置き換えた後のCSS:
body { padding-top: 50px; padding-bottom: 223px; background-image: url(replaced1 } .div1 { background-image: url("replaced1 } .div6 { background-image: url(replaced1 } .div7 { background-image: url("replaced1 }
検証2
先ほどと同じ条件。
・CSSのセミコロンを無しで、同じ行に2回登場させてみる。
・置き換える値を固定値にしてみる。
・正規表現は(.*)。
これで、occurrences="1"
を追記してみる。
web.config:
<outboundRules> <rule name="RewriteCSS" preCondition="ResponseIsCss"> <match filterByTags="None" pattern="/content/(.*)" occurrences="1"/> <action type="Rewrite" value="replaced2" /> </rule>
元のCSS:
body { padding-top: 50px; padding-bottom: 223px; background-image: url(/content/images/abc.png) url(/content/images/abc.png); } .div1 { background-image: url("/content/images/abc.png"); }
結果、置き換えられたCSS:
body { padding-top: 50px; padding-bottom: 223px; background-image: url(replaced2 } .div1 { background-image: url("/content/images/abc.png"); }
メモ API Mock Server
- 単純なGETだけなら、DropboxとかにJSONファイルを配置して公開したり
- MockServer
- Proxy とか
- JSON Server
- apiary
- Swagger
- paw(Macのみ)
- 効率の良いAPIモック作成について - Qiita
- そういえば、Azure の API Management に Mock 機能が How to mock responses in API Management | Azure API Management
- Amazon API Gateway もAmazon API GatewayでMockを定義してみる - Qiita
- APIドキュメント作成ツールまとめ - dackdive's blog
API 記述言語で定義しておけば後でどうにでもなる? Swagger Editor の Generate Server は、いろんなサーバーがあるけど静的生成。 モックからプロトタイプになるにつれ状況は変わりそう。