Determine the requested content type?

五迷三道 提交于 2019-12-18 05:38:01

问题


I'd like to write a Django view which serves out variant content based on what's requested. For example, for "text/xml", serve XML, for "text/json", serve JSON, etc. Is there a way to determine this from a request object? Something like this would be awesome:

def process(request):
    if request.type == "text/xml":
        pass
    elif request.type == "text/json":
        pass
    else:
        pass

Is there a property on HttpRequest for this?


回答1:


HttpRequest.META, more specifically HttpRequest.META.get('HTTP_ACCEPT') — and not HttpRequest.META.get('CONTENT_TYPE') as mentioned earlier




回答2:


'Content-Type' header indicates media type send in the HTTP request. This is used for requests that have a content (POST, PUT).

'Content-Type' should not be used to indicate preferred response format, 'Accept' header serves this purpose. To access it in Django use: HttpRequest.META.get('HTTP_ACCEPT')

See more detailed description of these headers




回答3:


in django 1.10, you can now use, request.content_type, as mentioned here in their doc




回答4:


As said in other answers, this information is located in the Accept request header. Available in the request as HttpRequest.META['HTTP_ACCEPT'].

However there is no only one requested content type, and this header often is a list of accepted/preferred content types. This list might be a bit annoying to exploit properly. Here is a function that does the job:

import re

def get_accepted_content_types(request):
    def qualify(x):
        parts = x.split(';', 1)
        if len(parts) == 2:
            match = re.match(r'(^|;)q=(0(\.\d{,3})?|1(\.0{,3})?)(;|$)',
                             parts[1])
            if match:
                return parts[0], float(match.group(2))
        return parts[0], 1

    raw_content_types = request.META.get('HTTP_ACCEPT', '*/*').split(',')
    qualified_content_types = map(qualify, raw_content_types)
    return (x[0] for x in sorted(qualified_content_types,
                                 key=lambda x: x[1], reverse=True))

For instance, if request.META['HTTP_ACCEPT'] is equal to "text/html;q=0.9,application/xhtml+xml,application/xml;q=0.8,*/*;q=0.7". This will return: ['application/xhtml+xml', 'text/html', 'application/xml', '*/*'] (not actually, since it returns a generator).

Then you can iterate over the resulting list to select the first content type you know how to respond properly.

Note that this function should work for most cases but do not handle cases such as q=0 which means "Not acceptable".

Sources: HTTP Accept header specification and Quality Values specification



来源:https://stackoverflow.com/questions/7459881/determine-the-requested-content-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!