404 Ошибка / Нет заголовка сообщения Access-Control-Allow-Origin в Symfony 4 + Приложение React. Как заставить работать маршрутизацию? - PullRequest
0 голосов
/ 15 марта 2020

Я создал простое приложение и хотел бы развернуть его на сервере. Я прохожу через это впервые - так что никакой предыдущий опыт я не смог бы извлечь из этого.

Общая проблема:

В приложении реализован React Router, но используется маршрутизация Symfony для вызовов в базу данных и из нее. Таким образом, для навигации по вкладкам приложения используется React Router, для загрузки в / из БД я намеревался использовать Symfony маршруты.

Все работает хорошо, когда я на локальном сервере. Но когда я вручную перетаскиваю файлы на сервер, приложение разрывает запросы на выборку.

Код компонента реакции:

 let targetUrl = `http://serverAddress.nazwa.pl/save`;

 let request = new Request(targetUrl, {
        body: formData,
        method: "POST",
        headers: {
            "Access-Control-Request-Method": "POST, GET, OPTIONS",
            "Origin": "http://mySimpleAppDomain.com.pl",
        }
    })
    fetch(request)
        .then((response) => response.json())

        .then((response) => {

            this.setState({
                isListActive: false,
                currentItems: [],
                currentItemsCounter: 0
            })
            document.getElementById("defNavEl").classList.add("default")
        })
        .catch((error) => {
            console.error('SAVE TO DB FETCH ERROR:', error);
        });

Symfony Код контроллера:

**
 * @Route("/save", name="save")
 */
public function save(Request $request)
{
    $shoppingList = new ShoppingList();
    $list = $request->request->all();

    if (count($list) > 0) {
        $em = $this->getDoctrine()->getManager();
        $shoppingList->setCreationDate(new \DateTime());
        $shoppingList->setName($list['name']);
        unset($list['name']);
        $shoppingList->setListItems($list);

        $em->persist($shoppingList);
        $em->flush();
        $results = $em->getRepository(ShoppingList::class)->listAllShoppingLists();
        $response = $this->json($results);

        $response->headers->set('Access-Control-Allow-Origin', 'https://localhost:8006');
        $response->headers->set('Content-Type', 'application/json');


        return $response;
    } else {
        return new Response();
    }
}

Nelmio Конфигурация пакета CORS:

nelmio_cors:
defaults:
    allow_credentials: false
    allow_origin: []
    allow_headers: []
    allow_methods: []
    expose_headers: []
    max_age: 0
    hosts: []
    origin_regex: false
    forced_allow_origin_value: ~
paths:
    '^/': null
        origin_regex: false
        allow_origin: ['*']
        allow_methods: ['*']
        allow_headers: ['*']
        expose_headers: ['Link']
        max_age: 3600

Наблюдения:

  1. Когда я пытаюсь получить данные в БД, я получаю следующее сообщение в консоли:

Доступ к выборке в 'http://example.nazwa.pl/save' из источника 'http://myappname.com.pl' был заблокирован политикой CORS: Нет 'Доступ Заголовок -Control-Allow-Origin 'присутствует на запрашиваемом ресурсе. Если непрозрачный ответ удовлетворяет вашим потребностям, установите режим запроса «no-cors», чтобы получить ресурс с отключенным CORS.

Это происходит несмотря на то, что я установил «Access-Control-Allow». Заголовок -Origin в действии, предназначенном для обработки запроса.

Когда я посылаю несколько тестовых запросов на http://serverAddress.nazwa.pl/save через Почтальона, я получаю ошибку 404.

Это, похоже, расходится с сообщение о политике CORS, упомянутое в пункте 1).

То, что я пытался (среди прочего):

Я пытался реорганизовать контроллер так, чтобы за него отвечало только одно действие для разных запросов. Но таинственным образом это не сработало. Это также не кажется хорошей идеей с точки зрения передовой практики.

Обращение за помощью:

У меня пока нет идей. Возможно, это что-то с конфигурацией .htaccess (я установил Apache Pack, который его сгенерировал). Я буду признателен за любые предложения или идеи, которые могут помочь мне двигаться вперед.

1 Ответ

1 голос
/ 15 марта 2020

Ваша Конфигурация указывает на ноль в этой строке:

'^/': null

Вам необходимо иметь конфигурацию, связанную с вашим маршрутом и доменом, как это: не стесняйтесь изменять ее в соответствии со своими потребностями и использовать конфигурацию .env, если это symfony 4:

  nelmio_cors:
    defaults:
        origin_regex: true
        allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
        allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
        allow_headers: ['Content-Type', 'Authorization']
        expose_headers: ['Link']
        max_age: 3600
    paths:  
        '^/save' :
          allow_origin:
            - '^http://serverAddress.nazwa.pl/'
            - '^http://localhost:[0-9]+'
            - '^http://serverAddress.nazwa.pl/save'
          #allow_origin: ['*']
          allow_credentials: true
          allow_headers: ['Authorization', 'X-Requested-With', 'content-type','Content-Type', 'Accept', 'Origin', 'X-Custom-Auth']
          allow_methods: ['POST', 'PUT', 'GET', 'DELETE','PATCH','OPTIONS']
          max_age: 3600
        '^/': null

Массив Paths примет маршрут и применит конфигурацию по умолчанию, указанную выше, а затем объединит ее с конфигурацией с указанием маршрута c, чтобы вы получили точную конфигурацию для каждого определенного маршрута. В этом примере по умолчанию все другие маршруты блокируют запросы cors, кроме / save route, которое разрешает домены или пути, определенные в массиве.

Обратите внимание, что: allow_origin: ['*'] позволит всем другим доменам запрашивать ресурс, который является не рекомендуется, если это не publi c api и любой скрипт может запросить его.

...