草庐IT

php - CakePHP 3 REST API + CORS 请求和 OPTIONS 方法

coder 2024-04-15 原文

我正在使用 CakePHP 3 开发 REST API。我想公开启用它,这样任何人都可以调用 API。 因此,我添加了此处定义的 cors header :http://book.cakephp.org/3.0/en/controllers/request-response.html#setting-cross-origin-request-headers-cors

我已经在 Dispatcher.beforeDispatch 和 Dispatcher.beforeDispatch 上实现了 EventListener 以准备 cors header 。

class ApiResponseHeaders implements EventListenerInterface
{

    /**
     * Event bindings
     *
     * @return array
     */
    public function implementedEvents()
    {
        return [
            'Dispatcher.beforeDispatch' => [
                'callable' => 'beforeDispatch',
                'priority' => 0
            ],
            'Dispatcher.afterDispatch' => [
                'callable' => 'afterDispatch',
                'priority' => 99999
            ]
        ];
    }

    public function beforeDispatch(Event $event)
    {
        $request = $event->data['request'];
        if ('OPTIONS' === $request->method()) {
            $event->stopPropagation();
        }
    }

    public function afterDispatch(Event $event)
    {
        $request = $event->data['request'];
        $response = $event->data['response'];

        $response->cors($request)
                ->allowOrigin('*')
                ->allowMethods(['GET', 'POST', 'OPTIONS'])
                ->allowHeaders(['Content-Type, Authorization, X-Requested-With, Accept'])
                ->allowCredentials()
                ->maxAge(0)
                ->build();

        if ('OPTIONS' === $request->method()) {
            $event->stopPropagation();
        }
    }

}

但问题是,当我从 AngularJS 向 API 端点发出 POST 请求时,它首先调用 OPTIONS 方法,然后调用 POST 方法。 CakePHP 不处理 OPTIONS 方法调用并返回:400 Bad Request

下面是示例请求和响应 header :

请求 header

OPTIONS /v1/account/login HTTP/1.1
Host: api.cake.dev
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:48.0) Gecko/20100101 Firefox/48.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Origin: http://demo.angular.dev
Connection: keep-alive

响应头

HTTP/1.1 400 Bad Request
Date: Wed, 07 Sep 2016 08:34:55 GMT
Server: Apache/2.4.17 (Win64) PHP/5.6.16
X-Powered-By: PHP/5.6.16
X-DEBUGKIT-ID: b4e5654a-cefb-43b7-bf19-4e8c7ffdb0e0
access-control-allow-origin: *
access-control-allow-methods: GET, POST, OPTIONS
access-control-allow-headers: Content-Type, Authorization, X-Requested-With, Accept
Access-Control-Allow-Credentials: true
access-control-max-age: 0
Content-Length: 147
Connection: close
Content-Type: text/html; charset=UTF-8

CakePHP 3 中是否有一种方法可以处理此 OPTIONS 请求并返回正确的响应,以便下一个 POST 请求正常工作?

请帮忙。 谢谢

最佳答案

对于 CakePHP 3.2+,我是这样做的:

public function beforeRender(event $event) {
    $this->setCorsHeaders();
}

public function beforeFilter(event $event) {
    if ($this->request->is('options')) {
        $this->setCorsHeaders();
        return $this->response;
    }
}

private function setCorsHeaders() {
    $this->response = $this->response->cors($this->request)
        ->allowOrigin(['*'])
        ->allowMethods(['*'])
        ->allowHeaders(['x-xsrf-token', 'Origin', 'Content-Type', 'X-Auth-Token'])
        ->allowCredentials(['true'])
        ->exposeHeaders(['Link'])
        ->maxAge(300)
        ->build();
}

这样,我什至可以处理 CakePHP 错误页面。

根据您的情况,您可以更改 allowHeaders 数组的值。

请记住,如果请求的 withCredentials 设置为 true,您将需要指定来源。

关于php - CakePHP 3 REST API + CORS 请求和 OPTIONS 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39365229/

有关php - CakePHP 3 REST API + CORS 请求和 OPTIONS 方法的更多相关文章

  1. ruby - Capistrano 3 在任务中更改 ssh_options - 2

    我尝试使用不同的ssh_options在同一阶段运行capistranov.3任务。我的production.rb说:set:stage,:productionset:user,'deploy'set:ssh_options,{user:'deploy'}通过此配置,capistrano与用户deploy连接,这对于其余的任务是正确的。但是我需要将它连接到服务器中配置良好的an_other_user以完成一项特定任务。然后我的食谱说:...taskswithoriginaluser...task:my_task_with_an_other_userdoset:user,'an_othe

  2. ruby-on-rails - rspec should have_select ('cars' , :options => ['volvo' , 'saab' ] 不工作 - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request

  3. ruby-on-rails - 获取 ActionController::RoutingError(当尝试使用 AngularJS 将数据发布到 Rails 服务器时,没有路由匹配 [OPTIONS] "/users" - 2

    尝试从我的AngularJS端将数据发布到Rails服务器时出现问题。服务器错误:ActionController::RoutingError(Noroutematches[OPTIONS]"/users"):actionpack(4.1.9)lib/action_dispatch/middleware/debug_exceptions.rb:21:in`call'actionpack(4.1.9)lib/action_dispatch/middleware/show_exceptions.rb:30:in`call'railties(4.1.9)lib/rails/rack/logg

  4. ruby - 为什么 Ruby 注入(inject)方法不能对没有初始值的字符串长度求和? - 2

    为什么下面的代码会报错?['hello','stack','overflow'].inject{|memo,s|memo+s.length}TypeError:can'tconvertFixnumintoStringfrom(irb):2:in`+'from(irb):2:in`blockinirb_binding'from(irb):2:in`each'from(irb):2:in`inject'from(irb):2如果传递了初始值,它就可以正常工作:['hello','stack','overflow'].inject(0){|memo,s|memo+s.length}=>18

  5. ruby - 求和 ruby​​ 哈希值 - 2

    我正在尝试从ruby​​散列中求和值,但使用inject或reduce都没有返回正确答案。似乎这些方法正在覆盖存储的当前值而不是对它们求和。我的哈希看起来像这样:@test=[{"total"=>18,"type"=>"buy","date"=>Thu,21Nov2013,"instrument_code"=>"food"},{"total"=>92,"type"=>"buy","date"=>Thu,14Nov2013,"instrument_code"=>"food"},{"total"=>12,"type"=>"buy","date"=>Wed,20Nov2013,"instru

  6. ruby-on-rails - 如何修复 `new' :String 的未定义方法 "Rack::Cors" - 2

    我是RubyonRails的新手,正在学习如何使用Angular,但是在我运行“geminstallrack-cors”之后,当我尝试启动Rails应用程序时,我保持收到此错误:C:/Ruby23-x64/lib/ruby/gems/2.3.0/gems/actionpack-5.1.1/lib/action_dispatch/middleware/stack.rb:35:in`build':undefinedmethod`new'for"Rack::Cors":String(NoMethodError)Didyoumean?nextfromC:/Ruby23-x64/lib/ruby

  7. ruby - 在 ruby​​ 中合并或求和 "keys"上的 2 个数组 - 2

    这是数组版本:Sum2hashesattributeswiththesamekey我有2个数组,例如:a=[[1,10],[2,20],[3,30]]b=[[1,50],[3,70]]我怎样才能对第一个值(如果存在)求和得到:c=[[1,60],[2,20],[3,100]] 最佳答案 你可以这样做:(a+b).group_by(&:first).map{|k,v|[k,v.map(&:last).inject(:+)]}首先,您使用+将数组放在一起,因为您不关心a和b,您只关心它们的元素。然后group_by按第一个元素对组合数组

  8. c# - 使用 JSON 请求和 RestSharp 通过 c# 上传文件 - 2

    在设法通过C#将数据加载到我的Rails服务器之后(查看here了解我在说什么),我现在尝试将一个文件连同其他数据一起上传到同一服务器。在Ruby中,我可以用代码做到这一点:require'HTTMultiParty'classReceiptCreateincludeHTTMultiParty#Logtofile#debug_outputFile.new("httparty1.log","w+")base_uri"localhost:3000"format:jsonheaders"Accept"=>"application/json"definitializeenddefpost(ma

  9. ruby - 在 ruby​​ 中对哈希中的数字求和 - 2

    我有一个这样的哈希。products={199=>['Shoes',59.99],211=>['Shirts',19.99],245=>['Hats',25.99],689=>['Coats',99.99],712=>['Beanies',6.99]}它有一个商品编号=>[product,price]。我想在不使用inject方法的情况下汇总所有价格。谁能帮帮我? 最佳答案 products.values.map(&:last).reduce(:+)#=>212.95 关于ruby-在r

  10. ruby-on-rails - rails 。对集合的特定属性求和 - 2

    我有一张发票list...@invoices_1_week=Invoice.order("due_dateDESC").where("status!='paid'ANDdue_date>=?ANDdue_date发票模型有一个总属性。我怎样才能得到@invoice_1_week集合中的总和?我知道我可以在这样的View中做到这一点......但我想知道是否有更多的Railsy方法来做到这一点。 最佳答案 这是一种Rails方法,使用ActiveRecord的sum方法:@invoices_1_week.sum("total")Her

随机推荐