Rails AJAX 请求用 post 正常,用 put 遇到问题

as181920 · 2013年05月06日 · 最后由 as181920 回复于 2013年05月08日 · 6737 次阅读

以下 ajax 发一个 post,一切正常

$.ajax
  url: "http://localhost:9000/notes/#{note_id}/entries/create_with_data"
  type: "post"
  data: data
  async: false
  complete: (data) ->
    window.open "/content/news"

以下照搬上面,换路由,且改 put 方法,居然就没有如预期正常响应了,不知为何,唯 log 是:Status: 204, Content-Length: , Response Time: 0.98ms

$.ajax
  url: "http://localhost:9000/notes/#{note_id}/entries/#{entry_id}/update_with_data"
  type: "put"
  data: data
  async: false
  complete: (data) ->
    window.open "/content/news"

如果不走 ajax,在 controller 里面用客户端 (Her/Faraday) 都是 ok 的。

服务端是 goliath+grape,类似如下,没做什么特别处理。

class MicroNotes < Grape::API
  format :json
  post "xxx" do
  end
  put "xxxx" do
  end

ps,我想又是那个 http 的基础问题我不会哈

Rails 的 PUT 是模拟出来的,你应该用 POST 请求发出去,带上一个 _method 参数,值是 PUT

比如 :

$.ajax({
  type: "POST",
  url: '/pages/1.json',
  data: { _method:'PUT', page : {...} },
  dataType: 'json'
});

#1 楼 @huacnlee PUT 应该也能正常用的,我用 PUT。

Grape 就不知道啦。

#1 楼 @huacnlee 模拟是为了浏览器兼容吧,但是直接用 put 应该也是可以的啊,至少我这用 angular.js update 直接用 PUT 没啥问题……

# angular/services/restful.js.coffee
# index:  GET  '/resource.json'
# save:   POST '/resource.json'
# get:    GET  '/resource/:id.json'
# update: PUT  '/resource/:id.json'
# edit:   GET  '/resource/:id/edit.json'
# new:    GET   just use get, id: 'new'
app.factory('RESTful', ['$resource',
  ($resource)->
    (resource_name) ->
      url = "/#{resource_name}/:id:format"
      defaults={format: '.json', id: '@id'}

      actions = {
        index:
          id: ''
          url: "/#{resource_name}:format"
          method: 'GET'
          isArray:false
        edit:
          url: "/#{resource_name}/:id/edit:format"
          method: 'GET'
        update:
          method: 'PUT'
        save:
          url: "/#{resource_name}:format"
          method: 'POST'
      }

      $resource url, defaults, actions
])

用 jquery put 的话倒是没试,因为已经把 jquery 去掉了……

#2 楼 @Rei 我看错了,他的不是 Rails

Status: 204 我觉得会不会是因为在 controller 里面没加 respond_to :json……

Rails 里面给自己用 put,是 ok 的(我以前代码里面用着是 ok 的,rails3.x); post,加 data 里面_method 这个方法我前面试过,也有问题,稍后我看看具体问题贴出来。

ps,我坦白其实这个问题描述的不是很清楚,不晓得怎么说的更明白,所以先贴出来碰运气,对不住大家。前面用 curl 方法调接口也有问题,反正混乱,等我理清了再补充保存和 log 信息。

#4 楼 @huacnlee

type: "post"
data: {_method: "put", xx: "xxx"}

log 如下, client: firebug: "NetworkError: 405 Method Not Allowed - http://localhost:9000/notes/2673/entries/10297/update_with_data" server: grape: [24234:INFO] 2013-05-07 11:39:24 :: Status: 405, Content-Length: 0, Response Time: 3.40ms

查了 http 的错误 code,没明白所以:)

grape 文档说,用不支持的 method 访问一个资源就会 405。我猜你访问的 url 没有对应到你想访问资源。

url: "http://localhost:9000/notes/#note_id}/entries/#entry_id}/update_with_data{"

这个真的映射到这个动作么?

put "xxxx" do
end

#8 楼 @Rei 我对照过好多次,用客户端 (gem: Her/faraday)访问的url和我这个js写明的url是一样的,但是log看是资源不允许(可能url不对可能method不对也可能有什么header有问题-根据http code)。

回头我再打着灯笼自己对比对比,也说不定真的老眼昏花没看清,但真的对比过几次了。

要出门了,回头再去看

需要 登录 后方可回复, 如果你还没有账号请 注册新账号