Можно ли ограничить маршрут только для AJAX?

40

Можно ли ограничить маршрут Symfony 2 только для запросов XHR? Я хочу объявить маршруты, доступные только через AJAX.

Я не хочу помещать некоторые дополнительные строки в каждое действие, подобное конкретному AJAX:

if ($request->isXmlHttpRequest()) {
    // do something
} else {
    // do something else
}

Я хочу определить:

  • одно правило для запросов AJAX
  • одно правило для запросов GET/POST к одному и тому же URL

чтобы обойти условия, описанные выше.

  • 0
    Зачем? Данные, которые они раскрывают, не будут доступны никому, кто все равно не сможет их получить.
  • 0
    Почему вы хотите это сделать?
Показать ещё 8 комментариев
Теги:

6 ответов

72
Лучший ответ

Я знаю, что этот вопрос немного старше, но между тем новый способ для этого был введен в Symfony 2.4.

Полностью настроенная настройка маршрута с условиями

Для ограничения ajax это будет выглядеть так:

contact:
    path:     /contact
    defaults: { _controller: AcmeDemoBundle:Main:contact }
    condition: "request.isXmlHttpRequest()"

Также возможно в аннотация:

/**
 * ContactAction
 *
 * @Route("/contact", name="contact", condition="request.isXmlHttpRequest()")
 */
  • 2
    Я думаю, что вы имеете в виду XMLHttpRequest , с заглавной XML.
  • 0
    О, спасибо, я исправил это сейчас.
Показать ещё 2 комментария
10

Моим советом было бы определить ваш собственный сервис маршрутизатора вместо default, который будет расширяться от Symfony\Bundle\FrameworkBundle\Routing\Router и переопределять метод resolveParameters() с использованием вашей собственной логики для обработки дополнительных требований.

И тогда вы можете сделать что-то подобное в своей маршрутизации:

your_route:
    pattern:  /somepattern
    defaults: { somedefaults }
    requirements:
        _request_type:  some_requirement
  • 0
    Это звучит действительно хорошо. Насколько важна производительность? Служба маршрутизации по умолчанию действительно плохо реализована? Я думаю, что я попробую.
  • 1
    Ну ... плохо или нет, это реализовано :) И самое лучшее в Symfony2 - это то, что вы можете переопределять сервисы и расширять базовые контроллеры любой функциональностью;)
2

Нет, вы не можете. Это не зависит от того, какую структуру вы используете, запросы AJAX в основном - это просто запросы к серверу. Нет надежного решения на 100%, просто "хаки".

  • 0
    На стороне сервера конкретного приложения я знаю, какая клиентская библиотека JavaScript используется. Поэтому это не хак, если мне нужно определенное поле заголовка http для конкретных маршрутов.
2

Я не уверен, что вы можете предотвратить запрос, однако вы можете проверить запрос XHR в Контроллере, проверив текущий запрос

Код будет выглядеть так:

if ($request->isXmlHttpRequest()) {
    // ...
}

Это не на 100% надежнее, из-за, среди прочего, несогласованности браузера и возможности вмешательства с помощью прокси. Однако это преобладающий метод проверки асинхронного запроса и рекомендуется многими. Если вы cr

Параметр URL

Альтернативой может быть добавление параметра в ваш URL для идентификации запроса как асинхронного. Это достигается добавлением ?ajax=1 к вашему URL. Затем проверьте параметр с помощью:

$AjaxRequest = $request->getParameter('ajax');
If($AjaxRequest == 1) {
    //...
}

Конечно, на этом этапе вы также можете создать конкретный маршрут, например. /ajax/index/.

  • 1
    Вместо использования > для подсветки кода, вы должны использовать 4 пробела или `.
  • 0
    @ j0k Спасибо, запомни это.
Показать ещё 3 комментария
1

То, что вы ищете, не существует в конфигурации маршрутизации Symfony.

Запрос:: isXmlHttpRequest даже не на 100% надежный и проверяет HTTP-заголовки, помещенные вашей библиотекой JavaScript:

Он работает, если ваша библиотека JavaScript установила заголовок HTTP с запросом HTTP. Известно, что он работает с Prototype, Mootools, jQuery.

  • 1
    Если я знаю, что моя бесшумная библиотека является специфической, то этот метод будет на 100% надежным.
0

Вы можете использовать требования для достижения описанного результата.
Итак, предположим, что вы определяете маршруты в формате yml, вам нужно сделать что-то вроде этого

my_route:
  pattern:  /path/to/route
  defaults: { _controller: CompanyBundle:Controller:Action, _format: html }
  requirements:
      _format:  xmlhttp /* not sure about the correct format because
                           i've never checked about */

И вы можете, конечно, использовать _method: POST или _method: GET

  • 0
    Это то, что я ищу. Но как называется конкретное значение?
  • 0
    Документация @crudolf о очень, очень, бедная. Я предлагаю начать с параметра, который я вам предлагаю, а затем попробовать что-то вроде «xml» или «ajax» напрямую. Сейчас я не на машине, которая позволяла бы мне делать такие попытки.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню