【问题标题】:format.js and format.json in same respond_toformat.js 和 format.json 在同一个 response_to
【发布时间】:2021-07-16 06:49:35
【问题描述】:

我有点困惑format.jsformat.json 两者如何协同工作

我有一个 ajax 请求,这是控制器操作:

def import_contacts_submit
    @new_file = ContactsFile.new(contacts_file_params)
    respond_to do |format|
      @new_file.save
      format.js
      format.json { render json: @new_file.errors, status: :unprocessable_entity } if @new_file.has_errors?
    end
  end

事实上,只有format.js 似乎在工作,因为我在 ajax 请求中的错误回调永远不会运行。但是,如果我将format.json 移动到format.js 上方,则ajax 中的错误回调将触发,format.js 永远不会运行。

【问题讨论】:

    标签: ruby-on-rails ajax


    【解决方案1】:

    Rails 通过读取 http 请求的 Accept 标头来确定要采用的格式:

    例子:

      def test
          f.js {
            render js: "Hello World"
          }
          f.json {
            render json: { foo: :bar }
          }
        end
    
    curl localhost:3000/test -H 'Accept: application/json'
    {"foo":"bar"}%
    
    curl localhost:3000/test -H 'Accept: application/javascript'
    Hello World%
    

    尝试在 XHR 调用中更改标题 accept,例如使用fetch时:

    fetch(url, { 
      headers: { 'Accept': 'application/json' },
    })
    

    在 jquery's.ajax 或原始 XHtmlRequest 中类似。

    更新 Rails 内容协商:

    Rails 具有确定格式的启发式方法。查看文档:https://api.rubyonrails.org/classes/ActionDispatch/Http/MimeNegotiation.html#method-i-formats

    formats.first会作为请求的“格式”,顺序是这样的。第一条规则将“获胜”:

    1. 一个名为“格式”的参数,例如?format=json
    2. 接受标头
    3. 路径后缀,例如/foo/bar.json
    4. 当 XHR -> 总是 js
    5. 否则为 HTML

    【讨论】:

    • 我仍然有疑问...所以如果我不指定accept 那么rails 将只运行它遇到的第一种格式?
    • @svelandiag 我已经用 Rails 内容协商的详细信息更新了答案。
    【解决方案2】:

    除了Accept 标头之外,您还可以在 url 中明确声明格式:

    some_path/to/import_contacts_submit.js
    some_path/to/import_contacts_submit.json
    

    【讨论】:

    • 感谢您的额外提示
    猜你喜欢
    • 1970-01-01
    • 2012-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多