Angular 6 + Laravel 5.6: ошибка CORS с httpClient.post - PullRequest
0 голосов
/ 11 октября 2018

Создан API с Laravel 5.6 и все конечные точки работают как положено с Почтальоном.Проблемы начались, когда я начал разрабатывать приложение Angular 6.Так как я работаю локально, я начал получать ошибки CORS в Chrome независимо от используемого метода http (httpClient).Поэтому я создал промежуточное программное обеспечение в Laravel для обработки запросов CORS.И все начало работать как положено, поэтому я подумал ... Теперь я столкнулся с другими проблемами.

Я использую действия контроллера Laravel по умолчанию для задач CRUD, поэтому я в основном использую маршрутизацию ресурсов (Route :: ресурс).Для пользовательских методов я использую Route :: post ().

Теперь странно то, что я могу отправить запрос на публикацию для пользовательских методов (Route :: post), но не к ресурсным маршрутам.

Пример:

//post requests to custom routes work as expected
Route::post('users/block', 'API\UserController@toggleBlock');
Route::post('users/access', 'API\UserController@sendAccess');

//post requests to resource routes nothing happens
Route::resource('settings', 'API\SettingController');
Route::resource('products', 'API\ProductController');

Если я изменю маршруты на следующие:

Route::get('settings', 'API\SettingController@index'); //works!
Route::post('settings', 'API\SettingController@store'); //nothing happens!!
Route::post('settings/bazinga', 'API\SettingController@store'); //works!!

Итак, из того, что я могу сказать,я не могу использовать один и тот же URI, даже если методы http отличаются.

Вот мое промежуточное программное обеспечение CORS:

public function handle($request, Closure $next)
{
    //apply cors only to api routes
    if (Request::segment(1) == 'api') {
        header("Access-Control-Allow-Origin: *");

        // ALLOW OPTIONS METHOD
        $headers = [
            'Access-Control-Allow-Methods' => 'POST, GET, OPTIONS, PUT, DELETE',
            'Access-Control-Allow-Headers' => 'Content-Type, X-Auth-Token, Origin, Authorization, Accept, Cache-Control',
        ];
        if ($request->isMethod("OPTIONS")) {
            // The client-side application can set only headers allowed in Access-Control-Allow-Headers
            return Response::make('OK', 200, $headers);
        }

        $response = $next($request);
        foreach ($headers as $key => $value) {
            $response->header($key, $value);
        }
    } else {

        $response = $next($request);
    }
    return $response;
}

Почему это происходит?Это связано с CORS?Так как с Почтальоном все работает как положено, это может быть связано с CORS, верно?

ОБНОВЛЕНИЕ: cURL Вывод

> curl 'https://api.project.localhost:34430/api/settings' -D -X OPTIONS -H 'pragma: no-cache' -H 'access-control-request-headers: authorization,' -H 'access-control-request-method: POST' -H 'origin: <http://localhost:4200>' -o output.txt

curl: (6)Не удалось разрешить хост: ОПЦИИ

ОБНОВЛЕНИЕ № 2: Угловой код

Метод сохранения:

save(settings: Setting[]): Observable<any> {
    const path = 'settings';

    const headers = {
      'Cache-Control': 'no-cache'
    };

    const params = { settings: settings };

    return new Observable(observer => {
        this.api.post(path, params, headers).subscribe(
            data => {
              // observable execution
              observer.next('Save Settings');
              observer.complete();
        },
        error => console.log(error) // error path
      );
    });
}

Способ отправки:

post(path: string, params: Object, headers?: any): Observable<ApiResponse> {
    const request = this.createRequestObject(path, params, headers);

    return this.http.post<ApiResponse>(
        request.endPoint,
        request.params,
        request.httpOptions
    );
}

private createRequestObject(path: string, params?: Object, headers?: any): ApiRequest {
    if (headers) {
      Object.assign(this.headers, headers);
    }

    const request = new ApiRequest();
    request.endPoint = this.endPoint + path;
    request.httpOptions = { headers: this.headers };
    request.params = params;

    return request;
}

ОБНОВЛЕНИЕ № 3: Chrome Dev Tools Console

Запрос на получение:

Get Request Console Log

Get Request Network Activity 1

Get Request Network Activity 2

Почтовый запрос:

Post Request Console Log

Примечание. Ничего не происходит в сетевой активности, когда я выполняю почтовый запрос.

Ответы [ 3 ]

0 голосов
/ 21 ноября 2018

Эта проблема из-за пропущенных и требуемых заголовков.Это должно быть сохранено и передано с обеих сторон (клиент и сервер).

Laravel:

Вы можете использовать пакет https://github.com/barryvdh/laravel-cors и изменять настройки в соответствии с требованиями.

Angular 6: Вы должны прочитать https://angular.io/api/common/http/HttpInterceptor. Вы можете создать перехватчик, который будет обрабатывать заголовки на стороне клиента.Я прилагаю шаблон, где вы можете проверить и использовать перехватчик.Проверьте ответ в данной ссылке.https://stackoverflow.com/a/53350123/3851720

0 голосов
/ 07 декабря 2018

В угловом конце, в служебном файле я добавил

const httpOptions = {
  headers: new HttpHeaders({ 
    'Access-Control-Allow-Origin':'*'
	})
};

перед декораторами.

И в конце Laravel в index.php внутри публичной папки, просто добавьте заголовки, как показано ниже

header('Access-Control-Allow-Origin: http://localhost:4200');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization');
0 голосов
/ 12 октября 2018

Можете ли вы проверить от curl или почтальона, какие выходные данные вы получаете для этой конечной точки с помощью OPTION?

curl '<path to endpoint>' -X OPTIONS -H 'pragma: no-cache' -H 'access-control-request-headers: authorization,' -H 'access-control-request-method: POST' -H 'origin: <http://localhost:4200>'

что-то похожее на запрос выше?

...