代码之家  ›  专栏  ›  技术社区  ›  Doug McClean

分析接受标题

  •  24
  • Doug McClean  · 技术社区  · 16 年前

    是否有人对解析HTTP接受头有任何建议(或正则表达式)?

    我正在尝试在ASP.NET MVC中进行一些内容类型协商。似乎没有一个内置的方式(这很好,因为这里有很多思想流派),但解析并不完全是琐碎的,如果有人已经做得很好并且愿意分享的话,我宁愿不重新发明轮子。

    7 回复  |  直到 6 年前
        1
  •  9
  •   Hank Gay    16 年前

    你见过吗? this article ?它提供了一个非常全面的实现来解析接受头,然后对它做一些有用的事情。

        2
  •  4
  •   Mark Bell    6 年前

    从.NET 4.5开始(我认为“微软”已经把框架版本的信息变得相当模糊了),你可以使用 one of the the built in parsers System.Net.Http.Headers :

    public IOrderedEnumerable<MediaTypeWithQualityHeaderValue> GetMediaTypes(string headerValue) =>
        headerValue?.Split(',')
            .Select(MediaTypeWithQualityHeaderValue.Parse)
            .OrderByDescending(mt => mt.Quality.GetValueOrDefault(1));
    

    然后你可以这样做:

    var headerValue = "application/json, text/javascript, */*; q=0.01";
    var mediaTypes = GetMediaTypes(headerValue);
    

    给你一个所有媒体类型的好列表,其中 首选 选项是第一项。这是Linqpad Dump mediaTypes 示例结果:

    LINQPad dump of results

    帽子尖到 this answer 为了让我走上正轨。

        3
  •  3
  •   Jrgns    15 年前

    我已经 written a parser 在PHP中。它并不复杂,但是它会按照优先顺序为您提供一个mime类型数组。

        4
  •  1
  •   Christophe Furmaniak    13 年前

    在PHP中找到另一个实现 here

        5
  •  1
  •   Adrian Gschwend    11 年前

    在阅读了xml.com文章之后,我决定自己不为accept头编写函数;)

    幸运的是,本文指向了一个好的库: https://code.google.com/p/mimeparse/ -在我的例子中,我需要它作为node.js模块: https://github.com/kriskowal/mimeparse

        6
  •  0
  •   Markus Jarderot    16 年前

    这个 RFC 相当复杂。如果正则表达式在哪里遵循这些规则,它将变为多行长。

    如果已经有了accept头,并且忽略了引号和参数,那么可以这样做来匹配每对:

    /([^()<>@,;:\\"\/[\]?={} \t]+)\/([^()<>@,;:\\"\/[\]?={} \t]+)/
    

    * 包含在字符类中,因此在regex中不需要任何特殊情况。

        7
  •  0
  •   goofballLogic    6 年前

    建立在 https://stackoverflow.com/a/49011308/275501 https://stackoverflow.com/users/43140/mark-bell 以上:

    public class MyController : Controller
    {
    
        [HttpGet]
        [Route("/test")]
        public ActionResult Index() {
    
            // does this request accept HTML?
            var acceptsHTML = IsAcceptable("text/html");
            var model = FetchViewModel();
            return acceptsHTML ? (ActionResult) View(model) : Ok(model);
    
        }
    
        private bool IsAcceptable(string mediaType) =>
            Request.Headers["Accept"].Any(headerValue =>
                !string.IsNullOrWhiteSpace(headerValue) &&
                headerValue.Split(",").Any(segment => MediaTypeHeaderValue.Parse(segment).MediaType == mediaType));
    
        private object FetchViewModel() {
    
            return new { Description = "To be completed" };
    
        }
    
    }