新手问题 客户端跨域 AJAX 请求, method 为 options 导致服务器端无法找到路由

btc022003 · 2016年09月01日 · 最后由 btc022003 回复于 2016年09月01日 · 2775 次阅读

我现在遇到一个问题,因为牵涉到跨域访问的需求。暂时比较纠结。get 和 post 请求都是没有问题的,当我使用 put 或者 delete 请求的时候就出问题了。

客户端的 js 代码部分,就是一个 jQuery 的 ajax 请求

$.ajax({
      type:"put",
      url:"http://localhost:3000/home/1",
      data:{name:"Jerry"},
      success:function(res){
        console.log(res);
      },
      error:function(err){
        console.log(err);
      }
    })

服务器端代码

def update
    p "do update id:#{params[:id]},age:#{params[:age]}"
    render json: {status:'y',msg:'修改成功'}
end

private
# 设置跨域访问的返回头
  def set_header
    response.headers["Access-Control-Allow-Origin"] = "*"
  end

命令行输出的 bug 内容

tarted POST "/home" for ::1 at 2016-09-01 16:00:40 +0800
  ActiveRecord::SchemaMigration Load (0.6ms)  SELECT "schema_migrations".* FROM "schema_migrations"
Processing by HomeController#create as */*
  Parameters: {"name"=>"Jerry"}
Can't verify CSRF token authenticity
"Jerry"
Completed 200 OK in 1ms (Views: 0.2ms | ActiveRecord: 0.0ms)
## post请求是可以的
---------

## put请求发送的method是options导致路由找不到
Started OPTIONS "/home/1" for ::1 at 2016-09-01 16:00:40 +0800

ActionController::RoutingError (No route matches [OPTIONS] "/home/1"):
  actionpack (4.2.6) lib/action_dispatch/middleware/debug_exceptions.rb:21:in `call'
  web-console (2.3.0) lib/web_console/middleware.rb:28:in `block in call'

浏览器请求信息截图

其实我只使用 get 和 post 请求就可以完全实现功能,但是为了长远来看,还是希望找到解决办法 帮忙看下,能不能提供个解决思路。

建议使用 https://github.com/cyu/rack-cors 来处理你的跨域问题,自行处理的话,你得手动处理 OPTIONS 问题。

我手动解决了,发现我的方法有些暴力 routes.rb 文件

match '*all', to: 'application#do_options', via: [:options]

application_controller.rb

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :null_session

  def do_options
    if request.method == 'OPTIONS'
      response.headers["Access-Control-Allow-Origin"] = "*"
      response.headers["Access-Control-Allow-Headers"] = "Origin, X-Requested-With, Content-Type, Accept"
      response.headers["Access-Control-Allow-Methods"] = "PUT,POST,GET,DELETE,OPTIONS"
      render :text => '', "content-type" => 'text/plain'
    end
  end
end
需要 登录 后方可回复, 如果你还没有账号请 注册新账号