【问题标题】:Symfony2 <a> link with 'post' or 'delete' or 'put' methodSymfony2 <a> 使用 'post' 或 'delete' 或 'put' 方法链接
【发布时间】:2013-06-05 08:42:08
【问题描述】:

我想通过&lt;a href&gt; 链接生成具有“PUT”或“POST”方法要求的网址。

由于我使用框架服务器端,因此我使用假表单来执行此操作 - 使用 PUT 方法的示例:

<form action="someActionUri" method="post">
      <input type="hidden" name="_method" value="PUT" />
      <input type="submit" value="GO PUT" />
</form>

但是,我想使用一个简单的&lt;a&gt; 链接:(

【问题讨论】:

  • 不可能做为一个链接,它不是特定于 Symfony2,它是 HTTP 的工作原理。
  • 只需创建一个带有“onclick”链接的表单即可发布表单

标签: symfony post hyperlink put http-method


【解决方案1】:

锚点&lt;a href="#"&gt; 将始终使用 GET 请求。没有办法修改它。但是,可以使用 Symfony 伪造 PUT 或 DELETE 请求。

Symfony Forms 会通过向表单添加隐藏字段来伪造动词。

<input type="hidden" name="_method" value="PUT" />

然后它在内部检查动词是否为 POST,检查 _method 参数并将动词从 POST 更改为 PUT。这仅适用于使用 POST 方法的 HTML 表单。

对于 GET 动词也可以这样做,但它需要使用事件侦听器。这是一个例子:

use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\HttpKernel;

class VerbListener
{
    public function onKernelRequest ( GetResponseEvent $event )
    {
        $request = $event->getRequest();

        if ( HttpKernel::MASTER_REQUEST === $event->getRequestType() 
                && $request->getMethod() === 'GET' )
        {
            if ( $request->query->get('_method') === 'PUT' ) {
                $request->setMethod( 'PUT' );
            }
        }
    }
}

并且该服务必须以比router_listener服务更高的优先级注册,这与到控制器的路由相匹配。

services:
    acme.verb.listener:
        class: Acme\Bundle\Listener\VerbListener
        tags:
            - { name: kernel.event_listener,
                event: kernel.request,
                method: onKernelRequest,
                priority: 100 }  

现在可以使用_method 参数生成链接

<a href="foo?_method=PUT"></a>

【讨论】:

    【解决方案2】:

    在路由文件中:

    entity_edit:
        pattern: /entity/{id}/edit
        defaults: {_controller: MyBundle:Entity:put}
    

    我的控制器(带有 fosRest):

    /**
     * @Rest\View()
     */
    public function putAction(Request $request, $id)
    {
    ...code   ...
    }
    

    我的树枝:

    <a href="{{ path('entity_edit', {'id': data.id} ) }}" >Edition</a>
    

    【讨论】:

      【解决方案3】:

      即使我喜欢@twifty 的响应,我认为听每一个请求只是为了适应其中的一些请求有点矫枉过正。 输出表单而不是链接要简单得多,因此您可以简单地使用:

      而不是&lt;a href="{{ path('my_route_with_put_method') }}"&gt;link&lt;/a&gt;
      <form action="{{ path('my_route_with_put_method') }}" method="POST">
          <button>link</button>
          <input type="hidden" name="_method" value="PUT">
      </form>
      

      您只需要注意,因为您使用的是块元素 (form) 而不是内联元素 (a),但您可以轻松解决这个问题(例如在表单或使用 CSS)

      【讨论】:

        猜你喜欢
        • 2020-12-13
        • 2012-08-03
        • 2017-02-17
        • 2014-03-20
        • 2015-06-03
        • 1970-01-01
        • 2023-03-09
        • 1970-01-01
        • 2015-05-17
        相关资源
        最近更新 更多