Ruby on Rails: How do detect if access by JSON?

前端 未结 6 553
旧时难觅i
旧时难觅i 2021-02-03 23:43

I got a GET URL that calls a controller method getInfo. It can be called by mydomain.com/getInfo.json?params=BLAHBLAH or mydomain.com/getInfo?params=BLAHBLAH

In the cont

相关标签:
6条回答
  • 2021-02-03 23:49

    Here is an actual somewhat contrived working example, that answers the question of how to detect if the call is JSON / XML API call vs an "HTML" call. (Accepted answer doesn't answer that question, just tells you how to respond to various formats)

    # We can use this in a before_filter
    skip_before_action :verify_authenticity_token, if: :api_request?
    
    # Or in the action
    def show
      @user = if api_request?
                User.where(api_token: params[:token]).first
              else
                User.find(params[:id])
              end
      respond_to do |format|
        format.html 
        format.json { render :json => @user }
      end
    end
    
    private
      def api_request?
        request.format.json? || request.format.xml?
      end
    

    Using a respond_to sets different types of responses, but it doesn't tell your application how the call was made unless you add some extra code that does it (see below for a crude example, just to illustrate the point.)

    I wouldn't recommend this, interrogating request is much safer, and 10x times more useful, as the approach below is only useful much later in the request lifecycle ( right before the response is sent back to the client). If you have any logic in your before filters this wouldn't work at all.

    # Have no way of using it in a before_filter
    # In your controller
    def show
      # I want to know if the call was JSON API - right here 
      # This approach wouldn't help at all. 
      @user = User.find(params[:id])
      respond_to do |format|
        format.html { @api_request = false}
        format.json { @api_request = true; render :json => @user }
      end
    end
    
    def api_request?
      @api_request
    end
    
    0 讨论(0)
  • 2021-02-03 23:52

    Within your controller's specific method, you can respond to different formats - for example:

    respond_to do |format|
      format.html
      format.json { render :json => @user }
    end
    

    You can respond to various formats (xml, js, json, etc) - you can get more information about respond_to and how to use it in your controller here:

    http://apidock.com/rails/ActionController/MimeResponds/InstanceMethods/respond_to

    0 讨论(0)
  • 2021-02-03 23:52

    If you need to check if it was an Ajax request you can check for a header[X-Requested-With] using request.xhr?

    Example code snippet

    if request.xhr?
      # Do the ajax stuff
    else
      # Do normal stuff
    end
    
    0 讨论(0)
  • 2021-02-03 23:55

    Yes. Within the controller you can call the request.format method to determine the format requested by the user.

    If you need more than just the format, you can look at request.url for the full URL. More details about the request object can be found here.

    0 讨论(0)
  • 2021-02-03 23:59

    A list of ways to check for json

    request.format == 'json'
    request.format == :json
    request.format.json?
    request.path.match('json')
    request.url.match('json')
    respond_to do |format|
      format.json { render json: [] }
    end
    

    You can also check if request was an ajax request

    request.xhr?
    
    0 讨论(0)
  • 2021-02-04 00:01

    As easy as do:

    request.path_parameters[:format] == 'json'
    
    0 讨论(0)
提交回复
热议问题