铁轨不重新定向PUT请求,而是将406寄回

发布于 2025-01-23 06:42:57 字数 1137 浏览 1 评论 0原文

我正在为我正在从事的学校项目制作钟声计划创建者。客户端的钟表创建在客户端上的创建与React组件一起处理,并且在更新时,组件调用此提取请求:

fetch(`/bell-schedules/${this.state.updatingId}`, {
                method: 'PUT',
                mode: 'cors',
                credentials: 'same-origin',
                headers: {
                    'Content-Type': 'application/json',
                    'Accept': 'text/html',
                },
                redirect: "follow",
                referrerPolicy: 'no-referrer',
                body: JSON.stringify({ name: this.state.name, schedule: json})})

在服务器上,这些请求由BellSchedulesController处理,以及处理此类型的路由的方法被编码为:

# PUT /bell-schedules/:id
  def update
    set_bell_schedule
    respond_to do |format|
      if @schedule.update(name: params[:name], schedule: params[:schedule])
        redirect_to action: 'index'
      else
        head 400
      end
    end
  end

索引是一种简单的方法,可以获取所有铃铛计划并将其渲染在表格中;该方法正常工作,其他路线指向它,并且它正常呈现。不幸的是,当我发送此PUT请求,而不是重定向到该页面显示钟表计划表时,我会恢复 406不可接受的。我还知道,贝尔时间表实际上正在更新,我已经检查了Rails控制台中的条目。

如何处理PUT请求中的重定向?我也遇到了与此相似的问题,但是我在那里发现了一个黑客。该黑客在这个方面无法使用。

I'm working on a bell schedule creator for a school project I'm working on. The bell schedule creation on the client is handled with a React component, and when it comes time to update, the component calls this fetch request:

fetch(`/bell-schedules/${this.state.updatingId}`, {
                method: 'PUT',
                mode: 'cors',
                credentials: 'same-origin',
                headers: {
                    'Content-Type': 'application/json',
                    'Accept': 'text/html',
                },
                redirect: "follow",
                referrerPolicy: 'no-referrer',
                body: JSON.stringify({ name: this.state.name, schedule: json})})

On the server, these requests are handled by the BellSchedulesController, and the method for handling this type of route is coded as so:

# PUT /bell-schedules/:id
  def update
    set_bell_schedule
    respond_to do |format|
      if @schedule.update(name: params[:name], schedule: params[:schedule])
        redirect_to action: 'index'
      else
        head 400
      end
    end
  end

Index is a simple method that gets all the bell schedules and renders them in a table; that method works fine, other routes point to it and it renders normally. Unfortunately, when I send this PUT request, rather than getting a redirect to that page showing the table of bell schedules, I instead get back a 406 Not Acceptable. I also know that the bell schedule is actually updating, I've inspected the entry in the rails console.

How do I handle redirects in PUT requests? I'm also having an issue similar to this in a POST request, but I've found a hack around it there; that hack won't work in this one.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

对风讲故事 2025-01-30 06:42:57

谷歌搜索您的问题似乎来自rection_to ... |格式| block,尝试摆脱它,看看它是否有帮助。您似乎无法正确使用它,您没有使用该格式做任何事情,也许这就是为什么它正在爆炸的原因。

Googling your problem it seems to come from the respond_to ... |format| block, try getting rid of it and see if it helps. You don't seem to be using it correctly, you are not doing anything with the format and maybe that's why it's blowing up.

温馨耳语 2025-01-30 06:42:57

编辑:此问题似乎是两倍 - 使用recond_to和重定向状态。 在format.html中更新我的答案:

  1. Wrap redirect_to。正如 @joel-blum所建议的那样,删除wends_to块完全解决了此问题。但是,我仍然需要303状态才能在本地
  2. 使用a
def update
  set_bell_schedule
  respond_to do |format|
    if @schedule.update(name: params[:name], schedule: params[:schedule])
      format.html { redirect_to action: 'index', status: :see_other }
    else
      head 400
    end
  end
end

> 303 (:see_other)重定向说明

wess_to wospy_to

使用 recond_to 在您的控制器操作中,您需要指定响应的目标。在这种情况下,您的请求为接受:文本/HTML,因此您需要将其指定为目标格式。 format.all或删除wonds_to在这里也可以工作,除非您需要基于covept标头返回不同的响应。

303重定向

标准301/302重定向危险的HTTP方法(GET以外的任何事物)通常不会受到浏览器的尊重。

浏览器将尝试使用与最初在以下方面提出的相同的HTTP方法重定向到indexput。这将导致404。将重定向状态设置为303确保浏览器使用get请求执行index重定向。

对GET请求的典型重定向响应表明请求资源已移动(暂时或永久)。

对于补丁/PUT/POST/DELETE,浏览器必须假设该资源是在预期位置找到的,但是自发出初始请求以来,其数据已更改。服务器只是通知客户端,此操作的响应存在于另一个位置。

对于HTTP合同的神圣性,需要不同的状态代码来指示这种情况。 303通知客户此响应位置的位置,并建议可以通过GET请求访问它。

Edit: the issue appears to be two-fold - the use of respond_to and the redirect status. Updating my answer as follows:

  1. Wrap redirect_to in format.html. As @joel-blum suggested, removing the respond_to block entirely also solves this issue; however, I still required the 303 status for this to work locally
  2. Use a 303 (:see_other) status code for the redirect
def update
  set_bell_schedule
  respond_to do |format|
    if @schedule.update(name: params[:name], schedule: params[:schedule])
      format.html { redirect_to action: 'index', status: :see_other }
    else
      head 400
    end
  end
end

Explanation

respond_to

When using respond_to in your controller actions, you need to specify what format(s) your responses are targeted for. In this case, your request is Accept: text/html, so you need to specify that as the target format. format.all or removing respond_to entirely would also work here, unless you need to return different responses based on the Accept header.

303 Redirect

Standard 301/302 redirects for dangerous HTTP methods (anything other than GET) generally won't be honored by the browser.

The browser will attempt to redirect to index using the same HTTP method that the request was initially made in: PUT. This will result in a 404. Setting the redirect status to 303 ensures that the browser performs the index redirect with a GET request.

A typical redirect response to a GET request indicates that the requested resource has moved (temporarily or permanently).

For PATCH/PUT/POST/DELETE, The browser has to assume that the resource was found at the expected location, but its data has changed since the initial request was made. The server is just informing the client that the response for this action exists at another location.

For the sanctity of the HTTP contract, a different status code is needed to indicate this situation. 303 informs the client of the location of this response location and suggests that it can be accessed with a GET request.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文