有没有一种方法可以通过自定义HTTP标头获取推荐网址?

时间:2020-01-10 20:09:16

标签: django django-views django-urls

我当前正在使用以下功能来获取引用视图:

def get_referer_view(request, default=None):   
    referer = request.META.get('HTTP_REFERER')
    if not referer:
        return default

    # remove the protocol and split the url at the slashes
    referer = re.sub('^https?:\/\/', '', referer).split('/')
    if referer[0] != request.META.get('SERVER_NAME'):
        return default

    # add the slash at the relative path's view and finished
    referer = u'/' + u'/'.join(referer[1:])
    return referer

如果我由于编程逻辑而重定向了view,例如...

return HttpResponseRedirect('dashboard')

...是否有一种无需使用HTTP_REFERER就可以获取引用视图的方法,以便可以在重定向的view中使用该变量?并非总是在浏览器的标题中进行设置。

请注意,因为视图是按语法重定向的,所以我无法使用POST来收集数据。

也许可以通过某种方式设置和检索自定义标头?

3 个答案:

答案 0 :(得分:2)

使用Django的中间件组件。

https://docs.djangoproject.com/en/3.0/topics/http/middleware/

类似的事情应该起作用:

class HTTPReferer:

    def __init__(self, get_response):
        self.get_response = get_response

def __call__old(self, request):
    # old
    referer = request.META.get('HTTP_REFERER', None)
    request.referer = referer
    # other business logic as you like it
    response = self.get_response(request)
    return response

def __call__(self, request):
    # reflecting last edit
    path = request.path
    response = self.get_response(request)
    response['previous_path'] = path
    return response

因此,您可以将所需的任何信息绑定到Django中每个请求/响应周期(您还可以设置自定义标头等)

在上面的示例中,HTTP_REFERER在请求对象中将以referer的形式提供。

编辑:我认为,您担心的是HTTP_REFERER并不总是由客户端填充;因此您可以将HttpRequest.path绑定到对自定义标头的每个请求。如果路径不够,您也可以保存请求参数。这就是我想的。然后,您将在最后一个路径中填充一个自定义标头。进一步,如果这还不够,您可以使用Django的URL resolver

答案 1 :(得分:1)

由于您控制发出请求的页面,因此请确定。将当前URL添加到某些标头中,然后将其提取到函数中,类似于:Add request header before redirection

所以代替这个:

def current_view():
   ...
   return HttpResponseRedirect('dashboard')

做这样的事情:

def current_view():
    ...
    response = redirect('/dashboard')
    response['source-view'] = request.resolver_match.view_name
    return response

这会产生带有自定义标头source-view的302,您可以在接收视图中提取该标头

答案 2 :(得分:0)

对于那些感兴趣的人,这是我得出的解决方案。技巧是在第一个存储view_namepath的请求之后设置cookie,然后调用它并保存到request,再渲染视图。

class MyMiddleware:

    def __init__(self, get_response):
        # One-time configuration and initialization.
        self.get_response = get_response

    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.

        # Add the referer cookie be accessible in request.response
        request.referer_view = request.COOKIES.get('referer_view', None)
        request.referer_path = request.COOKIES.get('referer_path', None)
        print('request.referer_view', request.referer_view)
        print('request.referer_path', request.referer_path)

        response = self.get_response(request)
        # Code to be executed for each request/response after
        # the view is called.

        # Set a cookie with the current view name that is cleared each time the view changes
        response.set_cookie('referer_view', request.resolver_match.view_name)
        response.set_cookie('referer_path', request.path)

        return response

然后,每次更改视图时,值都会在此循环中更新。