【问题标题】:Grab file extension from URL, in order to return correct Content-Type, using RegEx - Good practice?从 URL 获取文件扩展名,以便返回正确的 Content-Type,使用 RegEx - 好的做法?
【发布时间】:2013-06-27 04:31:17
【问题描述】:

我有两个问题:

No1:

我正在尝试提出一个正则表达式,它将返回在 URL 末尾找到的文件扩展名:

例如

假设 URL 中的文件扩展名只能以这种格式出现:

.../.../..../..../filename.fileextension.

我得到的文件扩展名如下(请原谅我受 C++ 启发的语法,阅读这样的代码对我来说更容易/更干净):

var fileExtension;
if (document.location.href.match(/.*\.(.*)$/) && document.location.href.match(/.*\.(.*)$/)[1])
{
  fileExtension = document.location.href.match(/.*\.(.*)$/)[1];
}

我希望上述 RegEx 的意思是匹配 URL 中最后一个点之后的所有内容。

是这种情况还是上述RegEx会失败的情况?如果是这样,正确的正则表达式是什么?

二号:

我之所以要执行上述操作,是因为我想设置我的第一个 Node.js 服务器,并且我正在努力使其尽可能高效。每当收到针对特定文件的请求时,我都想遍历所有可能的文件扩展名的数组,找到正确的文件扩展名,并在响应的头部返回适当的内容类型。出于这个原因,我创建了一个 JSON 文件 (content-types.json),其中包含所有可能的文件扩展名(准确地说是 646..)以及相关的内容类型。它看起来像这样:

{
  "3dm"       : "x-world/x-3dmf",
  "3dmf"      : "x-world/x-3dmf",
  "a"         : "application/octet-stream",
  "aab"       : "application/x-authorware-bin",
  "aam"       : "application/x-authorware-map",
   ......etc.
}

所以使用上面的 JSON 文件,我正在创建我的 server.js,如下所示:

var http = require('http');
var fs = require('fs');

var contentTypes = JSON.parse(fs.readFileSync("content-types.json"));

var host = "127.0.01";
var port = 1825;

var server = http.createServer(function (request, response)
{
  fs.readFile("." + request.url, function (error, data)
  {
    if (error)
    {
      response.writeHead(404, {"Content-type" : "text/plain"});
      response.end("something went wrong");
    }

    else if (request.url.match(/.*\.(.*)$/) && request.url.match(/.*\.(.*)$/)[1])
    {
      var extension = request.url.match(/.*\.(.*)$/)[1];
      var contentType;
      var found = false;

      // now I'll loop through the content-types object and look for a match
      // if a match is found then 
      // found = true; 
      // contentType = contentTypes[extension];

      if (!found)
      {
        response.writeHead(404, {"Content-type" : "text/plain"});
        response.end("wrong file extension");
      }

      else
      {
        response.writeHead(200, {"Content-type" : contentType});
        response.end(data);
      }
    }

    else
    {
      response.writeHead(404, {"Content-type" : "text/plain"});
      response.end("file extension not recognised");
    }
  });
});

server.listen(port, host, function ()
{
  console.log("listening " + host + ":" + port);
});

你认为上面的方法有效吗? 我只是想避免做类似“如果扩展名是 js 则使用此内容类型,如果是 css 则使用 this..etc”之类的事情。 但是,确实我正在读取/循环一个包含 646 个扩展的 JSON(针对每个请求),所以从性能的角度来看,我也不知道这是否明智。

我还想澄清一下,我不想在这种情况下使用 Express.js(尽管可以举个例子)。我试图让事情尽可能低级,因为我是菜鸟,我想先了解事情是如何运作的。

另外,正如你所知道的,我还没有编写合适的循环来寻找正确的内容类型,因为基本上我不知道如何循环遍历一个对象。我应该改用对象数组吗?但是在那种情况下,我将无法将其保存为我可以简单阅读的外部文件吗?我相信它必须是一个 JSON 文件。那么如何在上述场景中遍历该 contentTypes 对象,以便根据给定的扩展键获取适当的 contentType?

提前感谢您的帮助! :)

【问题讨论】:

    标签: javascript regex json node.js content-type


    【解决方案1】:

    只需将 mimes 放入“关联数组”(实际上只是一个具有命名属性的对象作为扩展名),然后使用扩展名作为键/索引

    mimes = {
       "js":"text/javascript",
       "css":"text/css",
       "json":"application/json"
    };
    var ext = request.url.split(".").pop();
    
    //Check if the extension mime association exists, if not default to text/html
    if( typeof(mimes[ext]) != "undefined" )
       mime = mimes[ext];
    else
       mime = "text/html";
    

    如果您需要从文件中加载 mime,您可以将 mime 保存在单独的 json 文件中并像 ajax 一样:

    mimes.json

    {
       "js":"text/javascript",
       "css":"text/css",
       "json":"application/json"
    }
    

    【讨论】:

    • 该死,你是对的。 :) 我不必显式地遍历对象,我需要做的就是contentType = contentTypes[extension];。我还在考虑数组。至于我的 RegEx,你的意思是我实际上根本不需要一个,对吧?我需要做的就是拆分点所在的 URL,这将返回一个包含 2 个元素的数组,基本上只使用第二个元素,如果我理解正确,这将始终有效?
    • 是的,只需将 url 拆分为每个 . pop 命令拉取末尾的任何一个,或者如果不存在句点则拉整个字符串
    • 酷,有道理。在性能方面呢?使用我创建的那个长 JSON 文件是否明智?无论如何都应该这样构建服务器吗?每次都使用一长串文件扩展名来尝试查找内容类型匹配,还是我让自己太难了,太迂腐了?还是标准做法只是使用较短的文件扩展名列表,因为 Web 开发人员将始终知道他们正在构建的特定网站将通过哪些特定文件扩展名请求?
    • 该列表应该只包含那些你愿意在你的应用程序中接受/使用的文件,否则它会太大而其他不被使用的将是多余的,例如你可以使用 jQuery ajax指定返回的数据应该是 html、json、xml,与 PHP 服务器语言相同,您将获得已上传的文件类型,因此您可以只整理出您想要的文件。如果你在几个不同的 js 文件中需要它,那么将它保存在一个单独的文件中是好的,因为它会减少用户浏览器需要执行 js 文件大小的请求
    【解决方案2】:

    如果 URL 类似于 http://www.example.com/mywebsite/mypage 怎么办?在这种情况下,问题中的正则表达式和 Patrick Evans 的回答都会给出 com/mywebsite/mypage 作为文件扩展名。你关心这个案子吗?如果是这样,您可能不得不单独对待它,例如如果第一步的输出包含/,则将其更改为html。

    【讨论】:

    • 是的,我也想过这种情况。或者如果 url 是 http://wrg.com/ersg/sg?wesdg=wsdg.wsg//somefile.js 怎么办?这是否会让我的服务器响应相关的 .js 文件(如果我碰巧有它?)即使它不应该?我真的不知道如何设置路由,它看起来仍然让我有点困惑.. 我知道 Express 应该使路由更容易,但我还没有找到任何关于这方面的教程,实际上讨论了我们所有的这些案例'已经提到..
    猜你喜欢
    • 2013-01-07
    • 1970-01-01
    • 2019-05-01
    • 1970-01-01
    • 2016-06-17
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    相关资源
    最近更新 更多