BootstrapのGlyphIconを使うとリモートでアイコンが出ないという話
MVCでNuGet使ってBootstrapインストールするとこんな感じにCSSとフォントが配置される。
んで、CSSのロードをBundleConfigあたりでこんな感じに
private static void RegisterStyleBundles(BundleCollection bundles) { bundles.Add(new StyleBundle("~/css") .Include("~/Content/bootstrap/bootstrap.css") .Include("~/Content/bootstrap/bootstrap-responsive.css") .Include("~/Content/bootstrap/bootstrap-theme.css") .Include("~/Content/bootstrap/dataTables.css") .Include("~/Content/bootstrap-mvc-validation.css") .Include("~/Content/bootstrap/signin.css") .Include("~/Content/body.css") .Include("~/Content/bootstrap-datepicker.css")); }
で、_layout.cshtmlあたりで
<head> <meta charset="utf-8" /> <title>@ViewBag.Title - hogehoge</title> <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> @Styles.Render("~/cs") @Scripts.Render("~/js") </head>
みたいな感じにすると。
で、ローカルで実行してると普通に表示されるのに、いざサーバーで実行するとglyphiconが全部おべんとばこ(□)に化けてしまうっつー現象にやられた。
原因
リモートで実行してるアプリから送られてくるHTMLを見ると
<head> <meta charset="utf-8" /> <title>Top - hogehoge</title> <link href="/favicon.ico" rel="shortcut icon" type="image/x-icon" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="/css?v=DO6j91cILO_L8-HWTgy7knOyUnxuUo4gQjQI7dSvpjg1" rel="stylesheet"/> <script src="/js?v=yQMfhDMNhFZ1m0ki0n3pWhCVm5vYHaVC1MllqiLohDc1"></script> </head>
な、感じにcssのURLが短縮(?)される。
フォントの場所はbootstrap.cssで
@font-face { font-family: 'Glyphicons Halflings'; src: url('../fonts/glyphicons-halflings-regular.eot'); src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg'); }
と相対パスで指定されてる。
css内のパスはCSSのURLがコンテキストパスとなった相対なので、上記HTMLだと
/../fonts/glyphicons-halflings-regular.*
を見に行ってめでたく404になると。
解決法
cssの実URLにある"/css"はBundleCollection.add()で登録したStyleBundleのラベルなので、ここを実URLに合うように変更すればOK。
bundles.Add(new StyleBundle("~/css") ... ↓ bundles.Add(new StyleBundle("~/Content/css/bootstrap") ...
<head> @Styles.Render("~/cs") ↓ @Styles.Render("~/Content/css/bootstrap") </head>
この時指定するラベル(/Content/css/bootstrap)と同じディレクトリがファイルシステム上実在するとそちらがロードされてしまうので注意。
というか
bootstrap.nugetで対処しておいて欲しいなぁ。