3. Proxy

3. Proxy

Về mặt ý tưởng đây có lẽ là cách đơn giản nhất. Nếu như không được phép thực hiện cross-domain AJAX request thì chúng ta chuyển sang same-domain request (haha). Nguyên lý là chúng ta sẽ chuẩn bị một proxy server đặt tại domain giống với domain gửi AJAX request, proxy này có nhiệm vụ nhận request và chuyển hướng request sang domain bên ngoài. Do thực hiện request đến domain bên ngoài ở phía server nên chúng ta sẽ không gặp phải bất kì hạn chế nào liên quan đến same-origin policy.

Việc chuẩn bị một proxy nói chung là phức tạp nhưng để demo cách thức hoạt động của phương pháp này mình xin được đưa ra 1 ví dụ với Rails. Đây là 1 cách implement đơn giản, proxy thực chất là một controller đặt tại http://my-domain.com/ajax, có nhiệm vụ nhận và chuyển hướng request đến http://other-domain.com.

# routes.rb
match "ajax/:path", to: 'ajax#create', via: :all, constraints: {path: /.*/}
class AjaxController < ActionController::Base
  skip_before_action :verify_authenticity_token

  def create
    # get request url
    path = params[:path].split('/').map{|i| ERB::Util.url_encode(i)}.join('/')
    url = 'http://other-domain.com' + '/' + path

    # remove some unnecessary parameters
    data = params.except(:controller, :action, :path)

    # get custom headers
    request_headers = {
      'CustomHeader' => request.headers['CustomHeader']
    }

    # send cross-domain request
    case env['REQUEST_METHOD']
    when 'GET'
      response = RestClient.get(url + '?' + data.to_query, request_headers)
    when 'POST'
      response = RestClient.post(url, data, request_headers)
    when 'PUT', 'PATCH'
      response = RestClient.put(url, data, request_headers)
    when 'DELETE'
      response = RestClient.delete(url + '?' + data.to_query, request_headers)
    end

    # return response
    render html: response.body.html_safe
  end
end

Khi gửi AJAX request thì chúng ta chỉ cần thay đổi url là được, lúc này request đã trở thành same-domain request (yeah)

$.ajax({
  url: 'http://my-domain.com/ajax/data'
})

Ưu điểm và nhược điểm

Ưu điểm:

  • Sử dụng được với tất cả các browser

  • Gửi được request với tất cả các loại HTTP method

  • Gửi được custom header kèm theo

Nhược điểm

  • Implement ở phía server phức tạp

  • Tốc độ chậm do phải request 2 lần

Tổng kết

tl;dr

Bài viết cũng đã khá dài nên có lẽ xin được kết thúc tại đây. Thay cho lời kết, mình xin tổng kết lại các đặc điểm của từng phương pháp trong bảng dưới để các bạn tiện tham khảo.

JSONP

CORS (XMLHttpRequest)

CORS (XDomainRequest)

Proxy

Implement phía client

Đơn giản

Đơn giản

Đơn giản

Không cần

Implement phía server

Đơn giản

Đơn giản

Đơn giản

Phức tạp

Các trình duyệt hỗ trợ

Tất cả

Hầu hết

IE 8, 9

Tất cả

HTTP method

GET

Tất cả

GET, POST

Tất cả

Gửi kèm header

Không thể

Có thể

Có thể (*)

Có thể

(*) Không thể gửi custom header

Cảm ơn các bạn đã theo dõi bài viết. (thanks)

Tài liệu tham khảo

Last updated

Navigation

Lionel

@Copyright 2023