Aiur

zellux 的博客

关于 respond_to 不同格式的顺序

Permalink

以前没注意过 Rails controller 中 respond_to 的格式顺序,后来碰到了一个诡异的 bug,才发现这里的顺序对程序行为是有影响的。bug 的现象是用某个应用商店桌面端浏览网站时,会出现返回 JSON 而不是网页的情况。由于当时报告错误的用户给出的 bug 描述是「点击链接后出现乱码」,导致 debug 一开始没找对方向,废了不少功夫才解决这个问题。

问题就出在不同格式的声明先后上,有问题的代码是:

1
2
3
4
respond_to do |format|
  format.json { render json: @items }
  format.html
end

有些浏览器或者内嵌了 WebKit 控件的程序,发送的 HTTP 请求头中,Content-Type 的值是 */*。这就导致 JSON 的 MIME (application/json) 匹配成功后返回给了浏览器。自然用户看到的是 JSON 而不是一个完整的网页。所以从这个角度来说,把 format.html 放在第一位比较合适(不知道有什么例外情况吗?)。

当然这个 bug 也可以说是程序或者控件的行为引起的,因为浏览器需要的 HTML 而不是 JSON,不应该发送格式为 */* 的请求。

评论