简体   繁体   English

js请求上的Rails ActionController::InvalidCrossOriginRequest

[英]Rails ActionController::InvalidCrossOriginRequest on a js request

I know this has been brought up a few times on SO but I cannot make inroads.我知道这已经在 SO 上提出了几次,但我无法取得进展。 I'm on Rails 5.0.7.2.我在 Rails 5.0.7.2 上。

I am getting ActionController::InvalidCrossOriginRequest thrown hundreds of times per day.我每天收到数百次ActionController::InvalidCrossOriginRequest Rollbar says it is mostly caused by Bingbot, and it's on my user signup modal, which is from Devise. Rollbar 说它主要是由 Bingbot 引起的,它在我的用户注册模式上,来自 Devise。 It's a GET request, and the path is /users/sign_up .这是一个 GET 请求,路径是/users/sign_up

NOTE: It's not a form.注意:这不是表格。 It's a modal that simply asks the user How would you like to sign up?这是一个简单地询问用户你想如何注册的模式? Email, Fb, Google auth, etc. Email、脸书、谷歌认证等

Basically I have some javascript actions on my site, picture like a reddit or stackoverflow upvote.基本上,我的网站上有一些 javascript 操作,例如 reddit 或 stackoverflow upvote 之类的图片。 I am not using remote: true on those links, but rather I have an $.ajax call that handles the upvote like so:没有在这些链接上使用remote: true ,而是我有一个$.ajax调用来处理upvote,如下所示:

var token = document.querySelector('meta[name="csrf-token"]').content;

$.ajax({
  // For the upvote, type will be POST
  type: $this.data('method'),
  beforeSend: function(xhr) {
    xhr.setRequestHeader('X-CSRF-Token', token)
  },
  url: $this.data('url'),
  success: function(data) {
    // Some cleanup...
  }
}); 

Once a logged out visitor tries to upvote, it fires the ajax request which is then halted (not authorized) and redirected, like this:一旦登出的访问者尝试投票,它就会触发 ajax 请求,然后该请求被暂停(未授权)并重定向,如下所示:

Started POST "/upvotes/toggle_vote"
Processing by UpvotesController#toggle_vote as */*
Completed 401 Unauthorized in 1ms (ActiveRecord: 0.0ms)


Started GET "/users/sign_up"
Processing by RegistrationsController#new as */*

Here's the Devise controller which I've overwritten:这是我已经覆盖的 Devise controller:

class RegistrationsController < Devise::RegistrationsController

  def new
    # ... other code        

    respond_to do |format|
      format.js   { render layout: false }
      format.html { respond_with self.resource }
    end
  end
end

Inside of /views/devise/registrations I have new.js.erb which opens up the "how would you like to sign up?"/views/devise/registrations里面我有new.js.erb ,它打开了“你想如何注册?” modal.模态的。

WHAT I'VE TRIED:我试过的:

  • I don't think solving it by adding protect_from_forgery except: :new is the right answer (as has been proposed in similar questions), since that's inherently not safe.我不认为通过添加protect_from_forgery except: :new是正确的答案(正如在类似问题中提出的那样),因为这本质上是不安全的。

  • I tried reordering the respond_to formats perthis but that makes the signup modal not open.我尝试按此重新排序respond_to格式,但这会使注册模式未打开。

  • I tried to throw in a format.any { raise ActionController::RoutingError.new("Not Found") } catch-all in the respond_to block but that did nothing to fix the error.我试图在 response_to 块中抛出respond_to format.any { raise ActionController::RoutingError.new("Not Found") } catch-all ,但这并没有解决错误。

  • As you can see in the $.ajax call above I even try to set the X-CSRF-Token header.正如您在上面的$.ajax调用中看到的那样,我什至尝试设置X-CSRF-Token header。

The full error text by the way is this:顺便说一句,完整的错误文本是这样的:

ActionController::InvalidCrossOriginRequest: Security warning: an embedded <script> tag on another site requested protected JavaScript. If you know what you're doing, go ahead and disable forgery protection on this action to permit cross-origin JavaScript

Any ideas?有任何想法吗?

Could it be that the authenticity token is getting lost since UpvotesController#toggle_vote redirects to RegistrationsController#new and changes from a POST to a GET?可能是因为UpvotesController#toggle_vote重定向到RegistrationsController#new并从 POST 更改为 GET,所以真实性令牌丢失了吗?

You need to send an authenticity token with ajax requests that modify resources in the server (post/put/patch/delete).您需要使用修改服务器中资源的 ajax 请求发送真实性令牌(发布/放置/补丁/删除)。 Usually, rails add it for you as a hidden field in the form.通常,rails 会为您将其添加为表单中的隐藏字段。

Adding this inside your form should do the trick:在表单中添加它应该可以解决问题:

<% hidden_field_tag :authenticity_token, form_authenticity_token %>

Couple of thoughts:几个想法:

  1. You shouldn't put the csrf token yourself, both jquery-rails or rails-ujs (I'm not sure which one you're using) do it for you;您不应该自己放置 csrf 令牌, jquery-railsrails-ujs (我不确定您使用的是哪一个)为您完成; with rails-ujs you need to use the Rails.ajax method使用 rails-ujs 你需要使用Rails.ajax方法

  2. There is no redirecting POST to GET and keeping the original POST headers , that means you indeed lose the csrf token in GET request (however you usually don't send or need a CSRF token in a GET request anyway so check why you are doing that maybe). 没有将 POST 重定向到 GET 并保留原始 POST 标头,这意味着您确实在 GET 请求中丢失了 csrf 令牌(但是您通常不会在 GET 请求中发送或需要 CSRF 令牌,因此请检查您为什么这样做也许)。

It looks like a CORS issue to me, just like the error suggest there I an API call made fro an embedded javascript which is on a different domain than the one defined on your server.对我来说,它看起来像一个 CORS 问题,就像错误提示我有一个 API 调用来自嵌入式 javascript 调用,该调用与您服务器上定义的域不同。 This triggers a CORS error.这会触发 CORS 错误。 Usually to fix CORS error you need to add a header Access-Control-Allow-Origin with the the domain of the website in the list of allowed domain.通常要修复 CORS 错误,您需要在允许的域列表中添加带有网站域的 header Access-Control-Allow-Origin。 You can easily do this with the rack cors gem: https://github.com/cyu/rack-cors您可以使用机架 cors gem 轻松做到这一点: https://github.com/cyu/rack-cors

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

相关问题 纯JavaScript的AJAX请求出现“ ActionController :: InvalidCrossOriginRequest”错误 - “ActionController::InvalidCrossOriginRequest” error with AJAX request by plain JavaScript 如何解决此错误“发生了一个ActionController :: InvalidCrossOriginRequest” - How to sort out this error “ A ActionController::InvalidCrossOriginRequest occurred in ” Rails 6.0.1 中 Ajax 请求的 ActionController::UnknownFormat 错误 - ActionController::UnknownFormat error with Ajax request in Rails 6.0.1 Rails 4 ActionController :: UnknownFormat format.js错误 - Rails 4 ActionController::UnknownFormat format.js error 使用 JavaScript 前端的 Rails API 获取请求中的 ActionController::UnknownFormat - ActionController::UnknownFormat in rails API fetch request with JavaScript Front-end ActionController::UnknownFormat 尝试将 .js 文件添加到我的 Rails 应用程序时 - ActionController::UnknownFormat when try to add .js file to my rails app Rails Form_Tag Ajax Format.js ActionController :: UnknownFormat - Rails Form_Tag Ajax Format.js ActionController::UnknownFormat Rails中的ActionController UnknownFormat错误4 - ActionController UnknownFormat Error in rails 4 ActionController :: RoutingError Rails和Angular - ActionController::RoutingError Rails and Angular Rails - Ajax:ActionController::UnknownFormat - Rails - Ajax: ActionController::UnknownFormat
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM