Có cách nào để có được một URL giới thiệu thông qua một tiêu đề HTTP tùy chỉnh không?


8

Tôi hiện đang sử dụng chức năng sau để có chế độ xem giới thiệu:

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

Nếu tôi chuyển hướng viewlà kết quả của logic lập trình, ví dụ ..

return HttpResponseRedirect('dashboard')

... có cách nào để có được chế độ xem giới thiệu mà không cần sử dụng HTTP_REFERERđể tôi có thể sử dụng biến đó trong chuyển hướng viewkhông? Điều này không phải lúc nào cũng được đặt trong các tiêu đề của trình duyệt.

Lưu ý vì các chế độ xem được chuyển hướng theo ngữ pháp, tôi không thể sử dụng POST để thu thập dữ liệu.

Có lẽ nó có thể thiết lập và lấy một tiêu đề tùy chỉnh bằng cách nào đó?


1
Bạn có kiểm soát chế độ xem trước đó và nó xuất phát từ ứng dụng của bạn không? Tôi sẽ chỉ thêm thông tin này trong tải trọng và phản hồi. Ví dụ như một tham số GET chuyển hướng ?came_from=inbox. Liên kết, Facebook, những người khác dường như làm điều đó, vì vậy nó nên được thực hành ok.
Mikko Ohtamaa

1
@MikkoOhtamaa vâng, tôi kiểm soát quan điểm. Trường hợp sử dụng thường là một chuyển hướng logic có điều kiện. Lý tưởng nhất là tôi muốn giữ sạch URL.
bí danh51

NHẬN tham số truy vấn là cách để đi. Thay thế, bạn có thể cố gắng lưu một số thông tin trạng thái trong dữ liệu phiên của người dùng, nhưng nó thường bị sụp đổ khi người dùng có nhiều cửa sổ trình duyệt mở và có xung đột ghi đè lên các biến phiên.
Mikko Ohtamaa

HttpResponseRedirectkhông thực sự có lập trình - nó trả về phản hồi http 302 thực tế và buộc trình duyệt thực hiện yêu cầu mới đối với url mới của chế độ xem đang được chuyển hướng đến ...
Oleg Russkin

Câu trả lời:


2

Sử dụng thành phần trung gian của Django.

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

Một cái gì đó như thế này sẽ hoạt động:

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

Vì vậy, bạn có thể liên kết bất kỳ thông tin nào bạn cần cho mỗi chu kỳ yêu cầu / phản hồi trong Django (bạn cũng có thể đặt tiêu đề tùy chỉnh, v.v ...)

Trong ví dụ trên HTTP_REFERERsẽ có sẵn trong đối tượng yêu cầu như referer.

EDIT: Tôi nghĩ rằng, mối quan tâm của bạn HTTP_REFERERlà không phải lúc nào cũng được khách hàng cư trú; vì vậy bạn có thể liên kết httpRequest.path với mọi yêu cầu được thực hiện cho một tiêu đề tùy chỉnh. Nếu đường dẫn không đủ, bạn cũng có thể lưu yêu cầu đối số. Đó là tất cả, tôi nghĩ. Sau đó, bạn có một tiêu đề tùy chỉnh được điền bởi đường dẫn cuối cùng. Hơn nữa, nếu điều này là không đủ, bạn có thể sử dụng trình phân giải URL của Django .


Cảm ơn, nhưng câu hỏi của tôi hỏi rõ ràng mà không sử dụng HTTP_REFERER
bí danh51

@ alias51, tôi hiểu, nhưng khi bạn có toàn quyền kiểm soát chu trình yêu cầu / phản hồi, tại sao bạn không sử dụng hơn một tiêu đề tùy chỉnh thay thế? Giống như: phản hồi ['I-AM-TRACKING-SOMETHING-IN-A-STATELESS-PROTOCOL'] = 'WHATEVER-YOU-NEED'. Tôi sẽ sửa đổi câu trả lời của tôi.
nhạc jazz

1

Vì bạn kiểm soát trang thực hiện yêu cầu, chắc chắn. Thêm URL hiện tại vào một số tiêu đề và trích xuất nó trong chức năng của bạn, tương tự như sau: Thêm tiêu đề yêu cầu trước khi chuyển hướng

vì vậy thay vì điều này:

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

làm một cái gì đó như thế này:

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

Điều này sẽ tạo ra 302 với tiêu đề tùy chỉnh source-viewmà bạn có thể trích xuất trong chế độ xem nhận


0

Đối với những người quan tâm, đây là giải pháp tôi bắt nguồn. Mẹo nhỏ là đặt cookie sau yêu cầu đầu tiên để lưu trữ view_namehoặc pathsau đó gọi nó và lưu vào requesttrước khi hiển thị chế độ xem.

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

Các giá trị sau đó cập nhật trong chu kỳ này mỗi khi thay đổi chế độ xem.


1
Điểm là, bạn đã có giải pháp nhận được hướng đến nó. Nếu bạn thích cookie hơn tiêu đề tùy chỉnh, tùy theo sở thích, tôi đã thích tiêu đề tùy chỉnh từ góc độ thiết kế, vì đường dẫn trước đó không ổn định và việc lưu trữ thông tin này trong cookie là không cần thiết. Rất vui được giúp bạn :-) Tôi thấy "giải pháp" của bạn quá muộn, nếu không, tôi sẽ không chỉnh sửa câu trả lời của mình.
nhạc jazz

Cảm ơn, tại sao bạn nghĩ rằng request.path không ổn định? Lý do tôi sử dụng cookie thay vì tiêu đề là các tiêu đề có thể dễ dàng thao tác và do đó kém an toàn hơn.
bí danh51
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.