繁体   English   中英

奇怪的“406不可接受”的错误

[英]Weird “406 not acceptable” error

当我尝试通过Javascript点击此操作时,我收到406 Not Acceptable错误:

  def show
    @annotation = Annotation.find_by_id(params[:id])

    respond_to do |format|
      format.html {
         if @annotation.blank?
           redirect_to root_path
         else
           redirect_to inline_annotation_path(@annotation)
         end
       }

       format.js {
         if params[:format] == "raw"
           render :text => @annotation.body.to_s
         else
           render :text => @annotation.body.to_html
         end
       }
    end
  end

这是来自jQuery,但我在发送之前做的正确:

  $.ajaxSetup({ 
    beforeSend: function(xhr) {
      xhr.setRequestHeader("Accept", "text/javascript");
    },
    cache: false 
  });

这是我的请求标题:

Host    localhost:3000
User-Agent  Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3
Accept  text/javascript
Accept-Language en-us,en;q=0.5
Accept-Encoding gzip,deflate
Accept-Charset  ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive  300
Connection  keep-alive
X-Requested-With    XMLHttpRequest
Content-Type    application/x-www-form-urlencoded

我破了这个案子!

我发送了一个带有get请求的format参数,以告诉服务器向我发送markdown而不是HTML。 这是我的Javascript:

$.get("/annotations/" + annotation_id, {format: 'raw'}, function(data) {
});

然后我在format.js块中寻找这个参数:

   format.js {
     if params[:format] == "raw"
       render :text => @annotation.body.to_s
     else
       render :text => @annotation.body.to_html
     end
   }

但显然format参数会混淆respond_to块。 我将它从{format: 'raw'}改为{markdown: 'true'}并且它有效。

我想这是Rails中的一个错误?

在respond_to块中包含“format.js”

当使用HTTPRiot从iPhone应用程序连接到JSON渲染Web应用程序时,这种情况发生在我身上。 似乎问题是由于Rails期望一个Accept HTTP标头,它很好,舒适。 因此,我使用Firefox的LiveHTTPHeaders扩展来查看没有406的头文件。无论如何,工作的Accept字符串是:

text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

我要研究的另一个领域是产生JSON的控制器。 如果控制器缺少一个format指令来指定它可以返回JSON作为响应,那么也可能导致406错误。

检查您的application.js是否需要jquery_ujs

//= require jquery_ujs

你可以尝试不设置Accept Header吗? 即使没有Accept标头,它实际上应该工作。

只需在控制器操作方法格式块中使用此代码:

format.js   { render :nothing => true }  

这是通过Apache提供的吗? 您可能需要查看http://forums.alwayswebhosting.com/showthread.php?p=8381 ,其中介绍了安全策略干扰请求的方案。

编辑 :上面引用的URL主张在整个站点上关闭请求嗅探安全策略,这会使站点容易受到攻击。 在.htaccess中将SecFilterEngine选项设置为Off,这是URL中规定的,应该只对问题的来源进行归零。 它不应被视为长期解决方案。

如果您使用的是jRails,这对我来说会造成很多问题,这是我的application.js文件:

$(document).ready(function () {
    $.ajaxSetup({
        beforeSend: function (xhr) {
            xhr.setRequestHeader("Accept", "text/javascript, text/html, application/xml, text/xml, */*");
        }
    });
});

对我来说,这是一个简单的before_filter,它限制了一个呈现js文件的动作,一旦我将:except => [:action]添加到before_filter块就可以了。

另一个阴险的“Gotcha”就是如果你用一个form_for调用你的控制器,那意外地有一个额外的不必要的参数 Rails可以将附加参数解释为格式请求,您将得到406。

例:

= form_for parking_permit, url: permit_group_parking_permits_path(@permit_group.id, useless_id), method: :get do |f| ...

在上面的示例中,您RAKE ROUTES并确定permit_group_parking_permits_path除了permit_group id之外不需要任何其他内容...

如果您看到正在调用您的方法,例如/model/action.1?blahblahblah ,那么“.1”就是您的提示。

这将返回406.我们不会谈论我花了多少时间在这上面。

当我忘记添加:remote => true到我的Ajax表单时,我遇到了这个问题。

我正在调用js格式的url但是在控制器中有这个:

respond_to do |format|
  format.html 
end

这在Safari中运行良好,但不适用于Firefox。

自然我错过了什么,应该是:

respond_to do |format|
  format.html
  format.js
end

现在两个浏览器都很好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM