无法使用 AJAX 获取 POST 数据

Can't get POST data with AJAX

我想在一个页面中显示 4 个对象,带有一个 "load more" 按钮,每次单击它都会显示另外 4 个对象。

我试着改编一个 PHP 脚本,它可以(测试)到 Symfony。 问题是我无法在我的 Symfony 函数中获取 POST 数据(页码),即使我可以在 chrome 开发人员工具栏中看到它...

我的控制器:

<?php
/**
 * Content controller.
 *
 * @Route("content")
 */
class ContentController extends Controller
{

/**
 * Lists all software.
 *
 * @Route("/software", name="content_software")
 * @Method({"POST", "GET"})
 */
public function softwareAction(Request $request)
{
    if ($request->request->get('page')){
        $page_number = filter_var($_POST["page"], FILTER_SANITIZE_NUMBER_INT,
                FILTER_FLAG_STRIP_HIGH);
        $item_per_page = 4;
        $position = (($page_number-1) * $item_per_page);
        $contents = $this->getRepo()->findBy(array(),null,$item_per_page,$position);
    }
    else
    {
        $contents = "didn't work";
    }
    return $this->render('content/index.html.twig', array(
            'contents' => $contents
    ));
}
}

index.html.twig :

{% 扩展 'loicCoreBundle::Default/layout.html.twig' %}

{% block body %}
{{ dump(contents) }}
<script type="text/javascript">
    var track_page = 1; //track user click as page number, right now page number is 1
    load_contents(track_page); //load content

    $("#load_more_button").click(function (e) { //user clicks on button
        track_page++; //page number increment everytime user clicks load button
        load_contents(track_page); //load content
    });

        //Ajax load function
        function load_contents(track_page){

            $.post( "{{ path('content_software') }}", {'page': track_page}, function(data){

                if(data.trim().length == 0){
                    //display text and disable load button if nothing to load
                    $("#load_more_button").text("No more records!").prop("disabled", true);
                }
            });
        }           
</script>
{% endblock %}

试试这个:

$request->request->get('page')

而不是这个:

$request->request->has('page')

如果不起作用,请尝试:

var_dump($request->request->all());

并检查变量

我不确定你的错误是从哪里来的,我做了一个类似的测试,它确实有效($request->request->get() 没有问题)。

然而,您也在为每个子请求加载完整模板 (index.html)。通常你想将这样的调用分成 api 之类的方法,但是对于简单的事情来说它有点愚蠢。

这是我测试的扩展/更新版本,我避免了所有 post 数据,只是将该方法用作开关。这工作得很好,所以尝试找出你错在哪里,使用它作为反射(或任何你喜欢用它做的事情)。请注意,这对测试数据使用了一个简单的 PHP 范围数组,而不是实体,但它应该保持相同的原则。

控制器

    /**
     * @Route(
     *      "software/{page}/{limit}",
     *      name="content_software",
     *      requirements = {
     *          "page": "[1-9]\d*",
     *          "limit": "[1-9]\d*"
     *      }
     * )
     */
    public function softwareAction(Request $request, $page = 1, $limit = 4) {
        if ($request->isMethod('POST')) {
            // replace these two lines with database logic (SELECT & LIMIT)
            $start = ($page - 1) * $limit;
            $items = array_slice(range(1, 10), $start, $limit); // Just using a simple item array [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] as test data

            $content = '';
            foreach ($items as $item) {
                $content .= $this->get('twig')->render('someItemTemplate.html.twig', ['item' => $item]);
            }

            return new Response($content);
        } else {
            // alternatively you can send out the default items here for the first get request
            // and use the same item template above with {% embed %} to render them in this template
            return $this->render('someTemplate.html.twig');
        }
    }

someTemplate.html.twig

<html>
    <head>
        <title>Cake or death?</title>
    </head>
    <body>
        <ul id="put-the-things-here"></ul>
        <button id="next_please">Ehh cake please!</button>

        <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
        <script>
            var pageTracker = 1,
                $next = $("#next_please"),
                $target = $('#put-the-things-here');

            load_contents(pageTracker);

            $next.click(function (e) {
                load_contents(++pageTracker);
            });

            function load_contents(page) {
                // using post just for the request method (page is in the url)
                $.post("{{ path('content_software') }}/" + page,
                    function (data) {
                        if (data) {
                            $target.append(data);
                        } else {
                            $target.append('<li>We are out of cake.</li>');
                            $next.attr('disabled', true);
                        }
                    }
                );
            }
        </script>
    </body>
</html>

someItemTemplate.twig

<li>Cake: {{ item }}</li>

我也觉得问题出在路由上。 仅使用 "POST" 方法时的错误消息:

"No route found for "GET /content/software”:方法不允许(允许:POST,DELETE)”。 因为当我通过单击 link 到达我的页面时,我到达了 GET 方法。

然而,当我点击我的 "load more" 按钮时,AJAX 工作并且我可以在我的 symfony 调试栏中看到我得到 POST 变量:

问题出在我第一次访问我的页面时。

@Jenne van der Meer:谢谢,但我不想使用 GET 参数。

我添加我的完整控制器代码,以防:

/**
 * Content controller.
 *
 * @Route("content")
 */
class ContentController extends Controller
{
    public function getRepo(){

        $em = $this->getDoctrine()->getManager();
        $repo = $em->getRepository('loicContentBundle:Content');

        return $repo;
    }

//  private $theRepo = getDoctrine()->getManager()->getRepository('loicContentBundle:Content');

    /**
     * Lists all content entities.
     *
     * @Route("/", name="content_index")
     * @Method("GET")    */
    public function indexAction(Request $request)
    {

        $contents = $this->getRepo()->findAll();
        $this->denyAccessUnlessGranted('ROLE_USER', null, 'Unable to access this page!');

                $formFilter = $this->createFormBuilder()
                ->add('_',     EntityType::class,array(
                                'class' => 'loicFilterBundle:Filter',
                                'multiple' => true,
                                'expanded' => true,
                                'choice_label' => function($value) {
                                return ($value->getName());
                                },
                                ))
                        ->add('Appliquer filtres', SubmitType::class)

                                ->getForm();

                                $formFilter->handleRequest($request);
                                $data = '';
                                if ($formFilter->isSubmitted() && $formFilter->isValid()) {
                                    $data = $formFilter->getData();
                                    $data = $data['_']->toArray();

                                    $contents = $this->getRepo()->findAll();
                                }
                                else
                                    {$contents = $this->getRepo()->findAll();
                                    }

        return $this->render('content/index.html.twig', array(
                'contents' => $contents,'formFilter' => $formFilter->createView(),'request' => $request
        ));
    }

    public function contentAction($categoryId)
    {   
        $contents= $this->getRepo()->findBy(
                array('contentCategorycontentCategory' => $categoryId),
                null,
                4

                );  
        return $contents;
    }

    /**
     * Lists all software.
     *
     * @Route("/software", name="content_software")
     */
    public function softwareAction(Request $request)
    {
        var_dump($request->request->all());
        $bla =  $request->request->get('page');
        if ($request->request->get('page')){
            $page_number = filter_var($_POST["page"], FILTER_SANITIZE_NUMBER_INT,
                    FILTER_FLAG_STRIP_HIGH);
            $item_per_page = 4;
            $position = (($page_number-1) * $item_per_page);
            $contents = $this->getRepo()->findBy(array(),null,$item_per_page,$position);
        }
        else
        {
            $contents = "didn't work";
        }
        return $this->render('content/index.html.twig', array(
                'contents' => $contents,'bla' => $bla
        ));

    }


    /**
     * Lists all videos.
     *
     * @Route("/videos", name="content_videos")
     * @Method("GET")
     */
    public function videoAction()
    {
        $contents = $this->contentAction(5);
        return $this->render('content/index.html.twig', array(
                'contents' => $contents,
        ));
    }

    /**
     * Lists all testimonies.
     *
     * @Route("/testimonies", name="content_testimonies")
     * @Method("GET")
     */
    public function testimoniesAction()
    {
        $contents = $this->contentAction(8);
        return $this->render('content/index.html.twig', array(
                'contents' => $contents,
        ));
    }

    /**
     * Lists all whiteBooks.
     *
     * @Route("/whiteBooks", name="content_whiteBooks")
     * @Method("GET")
     */
    public function whiteBooksAction()
    {
        $contents = $this->contentAction(3);
        return $this->render('content/index.html.twig', array(
                'contents' => $contents,
        ));
    }



    /**
     * Lists all actuality.
     *
     * @Route("/actuality", name="content_actuality")
     * @Method("GET")
     */
    public function actualityAction()
    {
        $contents = $this->contentAction(6);
        return $this->render('content/index.html.twig', array(
                'contents' => $contents,
        ));
    }

    /**
     * Lists all webinar.
     *
     * @Route("/webinar", name="content_webinar")
     * @Method("GET")
     */
    public function webinarAction()
    {
        $contents = $this->contentAction(4);
        return $this->render('content/index.html.twig', array(
                'contents' => $contents,
        ));
    }

    /**
     * Lists all blog posts.
     *
     * @Route("/blog", name="content_blog")
     * @Method("GET")
     */
    public function blogAction()
    {
        $contents = $this->contentAction(7);
        return $this->render('content/index.html.twig', array(
                'contents' => $contents,
        ));
    }


    /**
     * Creates a new content entity.
     *
     * @Route("/new", name="content_new")
     * @Method({"GET", "POST"})
     */
    public function newAction(Request $request)
    {   
        $em = $this->getDoctrine()->getManager();
        $content = new Content();
        $form = $this->createForm('loic\ContentBundle\Form\ContentType', $content);        
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($content);
            $em->flush($content);

            return $this->redirectToRoute('content_show', array('id' => $content->getIdcontent()));
        }

        return $this->render('content/new.html.twig', array(
            'content' => $content,
            'form' => $form->createView(),
        ));
    }



    /**
     * Displays a form to edit an existing content entity.
     *
     * @Route("/{id}/edit", name="content_edit")
     * @Method({"GET", "POST"})
     */
    public function editAction(Request $request, Content $content)
    {
        $deleteForm = $this->createDeleteForm($content);
        $editForm = $this->createForm('loic\ContentBundle\Form\ContentType', $content);
        $editForm->handleRequest($request);

        if ($editForm->isSubmitted() && $editForm->isValid()) {
            $this->getDoctrine()->getManager()->flush();

            return $this->redirectToRoute('content_edit', array('id' => $content->getIdcontent()));
        }

        return $this->render('content/edit.html.twig', array(
            'content' => $content,
            'edit_form' => $editForm->createView(),
            'delete_form' => $deleteForm->createView(),
        ));
    }

    /**
     * Deletes a content entity.
     *
     * @Route("/{id}", name="content_delete")
     * @Method("DELETE")
     */
    public function deleteAction(Request $request, Content $content)
    {
        $form = $this->createDeleteForm($content);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->remove($content);
            $em->flush();
        }

        return $this->redirectToRoute('content_index');
    }

    /**
     * Creates a form to delete a content entity.
     *
     * @param Content $content The content entity
     *
     * @return \Symfony\Component\Form\Form The form
     */
    private function createDeleteForm(Content $content)
    {
        return $this->createFormBuilder()
        ->setAction($this->generateUrl('content_delete', array('id' => $content->getIdcontent())))
            ->setMethod('DELETE')
            ->getForm()
        ;
    }
}

我的 Bundle/Resources/config/routing.yml 文件是空的。