解析接受标头

发布于 2024-07-08 09:52:13 字数 156 浏览 5 评论 0原文

有人对解析 HTTP Accept 标头有任何建议(或正则表达式)吗?

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

Does anyone have any suggestions (or a regular expression) for parsing the HTTP Accept header?

I am trying to do some content-type negotiation in ASP.NET MVC. There doesn't seem to be a built in way (which is fine, because there are a lot of schools of thought here), but the parsing is not entirely trivial and I would rather not re-invent the wheel if someone has already done it well and is willing to share.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

初与友歌 2024-07-15 09:52:13

您看过这篇文章吗? 它提供了一个非常全面的实现来解析 Accept 标头并随后用它做一些有用的事情。

Have you seen this article? It gives a pretty comprehensive implementation for parsing the Accept header and subsequently doing something useful with it.

ぽ尐不点ル 2024-07-15 09:52:13

从 .NET 4.5 开始(我认为微软现在已经让有关框架版本 < 4.5 的信息变得相当模糊),您可以使用 来自 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);

为您提供所有媒体类型的详细列表,其中首选选项是第一项。 以下是示例中 mediaTypes 结果的 LINQPad Dump

LINQPad 结果转储

这个答案,让我走上正确的道路。

As of .NET 4.5 (I think—Microsoft have made info on framework versions < 4.5 rather obscure these days), you can use one of the the built in parsers from System.Net.Http.Headers:

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

Then you can do something like this:

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

Giving you a nice list of all the media types, where the preferred option is the first item. Here's a LINQPad Dump of the mediaTypes result from the example:

LINQPad dump of results

Hat tip to this answer, for getting me on the right track.

蝶舞 2024-07-15 09:52:13

我用 PHP 编写了一个解析器。 它并不复杂,但它会按优先顺序为您提供一系列 mime 类型。

I've written a parser in PHP. It's not complex, but it will give you an array of mime types in order of preference.

娇女薄笑 2024-07-15 09:52:13

ASP.NET Core 解决方案:

我知道这是一个老问题,但对于任何像我一样使用 ASP.NET Core 的人来说,请注意,您可以在 上使用 GetTypedHeaders 扩展方法Request(或Response)对象来获取强类型标头信息,包括Accept

using Microsoft.AspNetCore.Http;

var accept = Request.GetTypedHeaders().Accept; // `Request` must be an `HttpRequest` instance
accept[0].MediaType
accept[0].Quality
// And so on...

ASP.NET Core solution:

I know this is an old question but for anyone using ASP.NET Core who might stumble into it like me, note that you can use the GetTypedHeaders extension method on the Request (or Response) object to get strongly-typed header information, including for Accept:

using Microsoft.AspNetCore.Http;

var accept = Request.GetTypedHeaders().Accept; // `Request` must be an `HttpRequest` instance
accept[0].MediaType
accept[0].Quality
// And so on...
忱杏 2024-07-15 09:52:13

在 php 此处 中找到了另一个实现

Found another implementation in php here

桃酥萝莉 2024-07-15 09:52:13

阅读 xml.com 文章后,我决定自己不为 Accept 标头编写函数;)

幸运的是,该文章指出了一个很好的库:https://code.google.com/p/mimeparse/ - 就我而言,我需要它作为 Node.js 模块:https://github.com/kriskowal/mimeparse

After reading the xml.com article I decided to not write a function for the Accept header myself ;)

Fortunately the article points to a good library: https://code.google.com/p/mimeparse/ - in my case I need it as a Node.js module: https://github.com/kriskowal/mimeparse

小帐篷 2024-07-15 09:52:13

基于 https://stackoverflow.com/a/49011308/275501 构建.com/users/43140/mark-bell">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" };

    }

}    

Building on https://stackoverflow.com/a/49011308/275501 from https://stackoverflow.com/users/43140/mark-bell above:

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" };

    }

}    
长途伴 2024-07-15 09:52:13

RFC 相当复杂。 如果正则表达式严格遵循这些规则,它会变得好几行长。

如果您已经有了 Accept-header,并忽略引号和参数,您可以执行以下操作来匹配每一对:

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

* 包含在字符类中,因此不需要任何特殊的正则表达式中的情况。

The RFC is quite complex. If the regex where to follow these rules to the letter, it would become several lines long.

If you already have the Accept-header, and ignore the quotes and the parameters, you could do something like this to match each pair:

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

* is included in the character class, so it does not need any special case in the regex.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文