2016-04-25 2 views
3

express.staticのルーティングで大文字と小文字が区別されるかどうかを設定するにはどうすればよいですか?例えばExpressがImage.jpegというローカルファイルを提供することにより、image.jpegの要求を処理する必要があるかどうか。Node.jsの大文字と小文字の区別静的資産の表現

express.Router([options])http://expressjs.com/en/4x/api.htmlで定義されている)を呼び出すときにはcaseSensitiveオプションがありますが、express.static(root, [options])(同じリンクのドキュメント)を呼び出すときはオプションではありません。

デフォルトでは、大文字と小文字を区別するボリューム(/ Mac OS X)から大文字小文字を区別するボリューム(/ Linux)に静的ファイルを提供する動作が異なります。この結果、アプリケーションでエラーが一貫しない - Mac OS Xでは大文字小文字の不一致がローカルでは機能しますが、Linuxサーバーには失敗します。

+0

私はむしろファイルパスの一貫性を保証しようとします。要求されたファイルが 'image.jpeg'の場合は、 'Image.jpeg'という名前を付けないでください。あなたがこれをするのを妨げる何かがありますか? –

+3

このケースは確かに一致しますが、この動作の不一致は、インフラストラクチャが誤植/開発者エラーに脆弱であり、コードが展開されるまで問題が取り上げられないことを意味します。コードをローカルでもサーバーでもエラーにするか、ローカルでサーバー上で成功させるかのどちらかです。 –

+0

'serve-static'には大文字と小文字の区別を指定するオプションがありません(上記のように一部のプラットフォームでは実現するのが難しいかもしれません)。あなたの最善の策は、静的ファイルを提供するサーバーのプロセスをカバーする統合テストを行うことです。 –

答えて

1

私はシンプルな代替ソリューションのためにも、いくつかのアドバイスを与えられた。

は、すべての静的ファイルとパスが小文字であるべきポリシーを設定します。

ファイルをチェックするビルドステップを追加して、ポリシーを適用します。

パスに大文字が含まれている場合、静的フォルダへの要求を拒否するミドルウェアを追加して、要求に対するポリシーを適用します。

1

私はこれも欲しかったので、不一致の場合の404要求への迅速な方法をノックアップしました。

これは特に効率的ではないので、私は開発でしか実行しません。ファイル名のみをチェックします。ファイルの上にあるフォルダの大文字小文字はチェックされません。私は数秒間readdir()の出力をキャッシュし、より効率的なバージョンを書いて、パス全体をチェックしている

var express = require('express'); 

var app = express(); 
// You can do this before or after the express() call 
// But it must come before express.static() is called 
var inDevelopment = (process.NODE_ENV || 'local') === 'local'; 
if (inDevelopment) { 
    require('./modules/makeExpressStaticCaseSensitive')(express); 
} 

app.use(express.static(path.join(__dirname, 'public_html'))); 

スクリプトmodule/makeExpressStaticCaseSensitive.js

module.exports = function (express) { 
    var fs = require('fs') 
    var pathlib = require('path'); 
    var parseUrl = require('express/node_modules/parseurl') 

    var oldStatic = express.static; 
    var newStatic = function (root, options) { 
     var opts = Object.create(options || null); 

     var originalHandler = oldStatic(root, options); 

     var wrappedHandler = function (req, res, next) { 
      var filepath = pathlib.join(root, parseUrl(req).pathname); 
      var dirpath = pathlib.dirname(filepath); 
      var filename = pathlib.basename(filepath); 

      // @todo Reading the entire directory listing and then searching it is quite inefficient for large folders 
      //  We should find a more efficient way to do this for one file at a time 
      fs.readdir(dirpath, function (err, files) { 
       if (err) return next(err); 

       var fileIsThere = files.indexOf(filename) >= 0; 
       if (fileIsThere) { 
        originalHandler(req, res, next); 
       } else { 
        res.status(404).end(); 
       } 
      }); 
     }; 

     return wrappedHandler; 
    }; 
    express.static = newStatic; 
}; 

、:どのようにそれを使用する

それはやや長いです。

関連する問題