• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    해결됨

안녕하세요 프로젝트를 react와 연동하기에 대해서 여쭈고 싶습니다 :)

22.05.30 09:46 작성 조회수 994

1

안녕하세요 이번에 강의를 다 듣고 또 게시판도 여러번 수행해서 정말 잘 되는것을 확인을 하였습니다 하지만 이번에 react와 함께 연동을 해서 view는 react를 사용하고 또 api 설계는 php로 한번 해보자 하고 도전을 해 보았는데요 

 

laravel에서는 굳이 cors를 지정하지 않아도 잘 연동이 되더라고요

 

하지만 이번 프로젝트는 어떻게 react를 사용해야하지.. 라고 막혔습니다 제가 생각했던 아이디어는

 

-frontend 폴더

-backend 폴더

를 따로 두고 proxy를 두어서 php 쪽에서 그냥 header로 cors를 넘겨주면 되지 않을까.. 라고 생각하고 들었는데요

https://github.com/DevelopJKong/php_react_project

일단 문제점은.. 제가 아직 실력이 부족해서 npm 으로 프로그램을 돌리는것이 아니기 때문에 되는게 아닐까? 라는 생각이 들었습니다

그래서 이번에는 상위 폴더에서 돌리는것이 아닌 따로따로서버를 켜서 해놨는데요 그래도.. 안되더라고요

혹시나 싶어서 CorsMiddleware를 만들어서 아래와 같이 만들어보고 post 로 보낼때 Route::add(x,y,[CorsMiddleware::class])

도 입력해봤는데요 코드는 아래와 같습니다

<?php

namespace App\Middlewares;

use Eclair\Routing\Middleware;

class CorsMiddleware extends Middleware
{
    public static function process()
    {
        header("Content-type: application/x-javascript;charset=utf-8");
        Header("Access-Control-Allow-Origin: *");
        Header("Access-Control-Allow-Methods: POST, GET, OPTIONS");
        Header("Access-Control-Allow-Headers:orgin, x-requested-with");
    }
}
<?php

use Eclair\Routing\Route;

use App\Middlewares\RequireMiddleware;
use App\Middlewares\CsrfTokenMiddleware;
use App\Middlewares\CorsMiddleware;

Route::add('post', '/api/auth', '\App\Controllers\AuthController::login',
    [CorsMiddleware::class]
);

조금 조언을 얻고자 이렇게 글을 쓰게 되었습니다 laravel에서는 그래도 해봤는데 laravel에서는 되더라고요 근데 왜이 프로젝트에서는 안될까? 라는 생각이 들었습니다 감사합니다 :)

 

 

 

 

 

 

 

답변 1

답변을 작성해보세요.

2

안녕하세요! 이해를 돕기 위해 프로젝트에서 사용한 프레임워크를 배제하고 이야기하겠습니다. Cors 가 궁금하시군요. 상황을 재현해보도록 합시다. 아래의 예시를 기반으로 프레임워크에서 프로젝트에서 어떻게 적용하면 좋을지 고민해보시기 바랍니다. 먼저 backend, frontend 에 index.php, index.html 을 만들어주고 아래와 같이 작성합니다. 프론트엔드에서 어떤 프레임워크가 사용되었는지는 중요하지 않습니다. 

* Cors 는 서브도메인, 도메인, 포트 등이 다르지 않은 경우에는 브라우저에서 제한하지 않을 것입니다. api.example.com 과 example.com 은 서브도메인이 다르기때문에 Cors 문제가 발생합니다.

 

backend/index.php

POST 요청에 대해 ajax 로 넘어온 파라매터를 받아온 다음 다시 그대로 반환합니다. 

switch ($_SERVER['REQUEST_METHOD']) {
    case 'POST':
        $data = file_get_contents('php://input');
        echo $data;
}

 

frontend/index.html

axios 를 사용하여 post 요청을 던져봅시다. 기본적으로 Content-Type: application/json 입니다.

<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

<script>
    axios.post('http://localhost:8080', { 
        data: 'Hello, world' // Content-Type: application/json
    }).then(({ data }) => {
        console.log(data);
    })
</script>

 

그 다음, 프론트와 백엔드에 대해 다른 서버를 켭니다. 서로 포트가 다름에 유의하십시오.

$ php -S localhost:8080 -t backend
$ php -S localhost:8081 -t frontend

Access-Control-Allow-Origin

프론트엔드인 localhost:8081 에 진입하여 콘솔을 살펴보면 Cors 오류를 던집니다.

Access to XMLHttpRequest at 'http://localhost:8080/' from origin 'http://localhost:8081' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

에러를 보니 Access-Control-Allow-Origin 를 설정하라는 이야기인 것 같습니다. 요청을 허용할 Origin 을 설정하라는 이야기입니다. 설정해봅시다.

backend/index.php

header("Access-Control-Allow-Origin: http://localhost:8081");
// header("Access-Control-Allow-Origin: *");

 

Access-Control-Allow-Headers

하지만 다시한번 요청해보면 또 에러를 던집니다. 이번에는 Access-Control-Allow-Headers 를 설정하지 않아서 생긴 오류입니다.

Access to XMLHttpRequest at 'http://localhost:8080/' from origin 'http://localhost:8081' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.

문구를 읽어보면 이런 표현이 있습니다. 

Request header field content-type is not allowed

content-type 헤더가 서버에서 허용되지 않았다는 이야기입니다. axios 요청을 까보면 기본적으로 content-type 을 같이 던집니다. 

Access-Control-Request-Headers: content-type

 

서버에 Access-Control-Allow-Headers 를 응답에 추가합니다.

backend/index.php

header("Access-Control-Allow-Headers: content-type");
// header("Access-Control-Allow-Headers: *");

 

이제 최종적으로 서버의 코드를 살펴보면 다음과 같습니다.

backend/index.php

header("Access-Control-Allow-Origin: http://localhost:8081");
header("Access-Control-Allow-Headers: content-type");

switch ($_SERVER['REQUEST_METHOD']) {
    case 'POST':
        $data = file_get_contents('php://input');
        echo $data;
}

 

이제 다시 요청을 해보면 오류없이 데이터가 콘솔에 출력된 것을 볼 수 있을겁니다. 라라벨은 내부적으로 처리해주는 일이 있어서 그럴 것이고, 우리는 사실상 날것 그대로를 이야기하고 있으므로 설정해주어야 하는 것들이 있답니다.

 

도움이 되셨으면 좋겠습니다 :)

잘 해결 했습니다! 잘 전달이 되는거 같습니다 너무너무 감사합니다 얼른 라라벨 강의가 나왔으면 좋겠습니다 바로 결제 대기중입니다 항상 좋은 강의 감사합니다 :)