programing

React에서 CORS 문제를 해결하는 방법JS

newnotes 2023. 3. 6. 21:26
반응형

React에서 CORS 문제를 해결하는 방법JS

리액트 어플리케이션에서 Axios를 통해 API 호출을 시도하고 있습니다.하지만 브라우저에 이 CORS 문제가 뜨네요.내부적으로 API에 접근할 수 없기 때문에 클라이언트 측에서 이 문제를 해결할 수 있는지 궁금합니다.첨부한 것은 제 코드입니다.

const response = axios({
  method: "post",
  dataType: "jsonp",
  url: "https://awww.api.com",
  data: {
    appToken: "",
    request: {
      applicationName: "ddfdf",
      userName: "jaime@dfd.com",
      password: "dfd",
      seasonIds: [1521ddfdfd5da02],
    },
  },
});

return {
  type: SHARE_REVIEW,
  payload: "response",
};

WebPack.config.js를 첨부합니다.

module.exports = {
  entry: ["./src/index.js"],
  output: {
    path: __dirname,
    publicPath: "/",
    filename: "bundle.js",
  },
  module: {
    loaders: [
      {
        exclude: /node_modules/,
        loader: "babel",
        query: {
          presets: ["react", "es2015", "stage-1"],
        },
      },
      { test: /\.json$/, loader: "json-loader" },
    ],
  },
  resolve: {
    extensions: ["", ".js", ".jsx"],
  },
  devServer: {
    historyApiFallback: true,
    contentBase: "./",
  },
  node: {
    dns: "mock",
    net: "mock",
  },
};

"Traccession Media"의 튜토리얼에서 찾은 가장 간단한 방법은 https://cors-anywhere.herokuapp.com을 'traccessos' 또는 'traccession' api로 사용하는 것입니다.

https://cors-anywhere.herokuapp.com/{type_your_url_here} 

예.

axios.get(`https://cors-anywhere.herokuapp.com/https://www.api.com/`)

이 경우 URL을 다음과 같이 편집합니다.

url: 'https://cors-anywhere.herokuapp.com/https://www.api.com',

이상적인 방법은 서버에 CORS 지원을 추가하는 것입니다.

별도의 jsonp 모듈을 사용해 볼 수도 있습니다.내가 아는 한 악시오는 jsonp를 지원하지 않는다.그래서 당신이 사용하고 있는 방법이 유효한 jsonp 요청으로 적합한지 잘 모르겠습니다.

CORS를 사용하다서버와 클라이언트의 프록시 역할을 하는 nginx 서버를 사용하여 코드를 전개해야 합니다.우리를 속일 수 있는 것은proxy_pass는 특정 이 "nginx"가 되도록 합니다.proxy_pass는 보통 합니다.통상, CORS 의 문제는, Web 사이트 도메인의 변경에 의해서 발생합니다.클라이언트와 서버의 페이스로서 기능하는 단일 프록시가 있는 경우, 브라우저는 서버와 클라이언트가 같은 도메인에 있는 것으로 착각합니다.Ergo no CORS.

이 예를 들어 보겠습니다.

는 「」입니다.my-server.com의 고객은 '''입니다.my-client.com 를 다음과같이 합니다.nginx 는 nginx 입니다.

// nginx.conf

upstream server {
    server my-server.com;
}

upstream client {
    server my-client.com;
}

server {
    listen 80;

    server_name my-website.com;
    access_log /path/to/access/log/access.log;
    error_log /path/to/error/log/error.log;

    location / {
        proxy_pass http://client;
    }

    location ~ /server/(?<section>.*) {
        rewrite ^/server/(.*)$ /$1 break;
        proxy_pass http://server;
    }
}

서 ★★★★my-website.com는, 코드에 액세스 할 수 있는 Web 사이트의 이름(프록시 Web 사이트의 이름)이 됩니다.되면 .하다

  • 은 API에서 됩니다.my-server.com/<API-path>로로 합니다.my-website.com/server/<API-path>

nginx에 대해 잘 모르실 경우 문서를 검토하시기 바랍니다.

위의 설정에서 무슨 일이 일어나고 있는지 간단히 설명하려면 다음 절차를 따릅니다.

  • upstream는, 합니다.
  • serverblock x nginx 서 、 nginx block 、 nginx block block block block block block block block block block block block block block block block block block block block block block block block block 。
  • 이 있는 , 「」는 「」입니다.server_name는 현재 요청을 처리하기 위해 사용되는 블록을 식별하기 위해 사용됩니다.
  • error_log ★★★★★★★★★★★★★★★★★」access_log디렉티브는 로그 파일의 위치를 정의하기 위해 사용됩니다(디버깅에 사용).
  • location블록은 다양한 유형의 요청 처리를 정의합니다.
    1. 은 로케이션블록으로 하는 모든 합니다./로 리다이렉트 됩니다.
    2. 은 '다'로 하는 모든 합니다./server/<API-path>이러한 요구는 모두 서버로 리다이렉트 합니다.

★★★★★★/server클라이언트측 요구와 서버측의 요구를 구별하기 위해서 사용되고 있습니다.도메인이 동일하기 때문에 요청을 구분할 수 있는 다른 방법은 없습니다. 붙여야 을 명심하세요./server이러한 모든 사용 사례에서.기타 문자열로 변경할 수 있습니다. /my-server/<API-path>,/abc/<API-path> 등등.

이 방법으로도 충분히 대응할 수 있지만, 이러한 상황에 대처하는 것이 이상적이기 때문에 서버에 CORS 지원을 추가하는 것을 강력히 추천합니다.

개발 중에 이 모든 것을 피하고 싶다면 이 크롬 확장을 사용할 수 있습니다.개발 중에 교차 도메인 요청을 수행할 수 있어야 합니다.

임시로 CORS라는 크롬 플러그인으로 이 문제를 해결합니다.BTW 백엔드 서버는 프런트엔드 요구에 적절한 헤더를 송신해야 합니다.

@Nahush의 답변 외에 프로젝트에서 이미 Express 프레임워크를 사용하고 있다면 역프록시에 Nginx를 사용하는 것을 피할 수 있습니다.

보다 간단한 방법은 express-http-proxy를 사용하는 것입니다.

  1. 려려를 npm run build들을만만 만만만다다

    var proxy = require('express-http-proxy');
    
    var app = require('express')();
    
    //define the path of build
    
    var staticFilesPath = path.resolve(__dirname, '..', 'build');
    
    app.use(express.static(staticFilesPath));
    
    app.use('/api/api-server', proxy('www.api-server.com'));
    

리액트 코드에서 /api/api-server를 사용하여 API를 호출합니다.

그 때문에, 그 브라우저는 같은 호스트에 요구를 송신해, 내부에서 다른 서버로 요구를 리다이렉트 합니다.브라우저는 그것이 같은 발신기지로부터 송신되고 있는 것을 인식합니다).

React 개발 서버가 요청을 해당 서버에 프록시하도록 할 수 있습니다. 됩니다.url: "/" 다음 줄을 .package.json

"proxy": "https://awww.api.com"

여러 소스에 CORS 요청을 보내는 경우 직접 프록시를 구성해야 합니다. 이 링크는 Create React App Proxying API 요청을 설정하는 데 도움이 됩니다.

http-proxy-middleware를 사용하여 CORS를 바이패스하도록 익스프레스 프록시 서버를 설정할 수 있습니다.

const express = require('express');
const proxy = require('http-proxy-middleware');
const path = require('path');
const port = process.env.PORT || 8080;
const app = express();

app.use(express.static(__dirname));
app.use('/proxy', proxy({
    pathRewrite: {
       '^/proxy/': '/'
    },
    target: 'https://server.com',
    secure: false
}));

app.get('*', (req, res) => {
   res.sendFile(path.resolve(__dirname, 'index.html'));
});

app.listen(port);
console.log('Server started');

리액트 앱에서 모든 요청을 /proxy 엔드포인트로 전송하고 원하는 서버로 리디렉션합니다.

const URL = `/proxy/${PATH}`;
return axios.get(URL);

서버측 코드에 Cors 지원이 없는 것이 틀림없습니다.Asp.net core 에서는, 다음의 방법으로 실행할 수 있습니다.public void Configure Services()에서 다음 콜을 추가합니다.IServiceCollection services)를 Startup.cs 파일에 저장합니다.

public void ConfigureServices(IServiceCollection services)
{
     app.UseCors(options => 
                options.WithOrigins("http://localhost:3000").AllowAnyHeader().AllowAnyMethod());
}
        

문제가 발생하여 개발 환경(로컬 호스트)에 있었기 때문에 클라이언트와 서버의 기원이 달랐습니다.

  • 마지막으로 로컬 호스트에서 실행되는 간단한 커스텀 프록시 서버를 작성함으로써 문제를 해결했습니다(서버 코드에 액세스할 수 없었기 때문에 응답 원본에서 cors를 허용해야 했습니다).

localhost:3001에서 실행되는 단순 프록시 서버:

const express = require("express");
const { createProxyMiddleware } = require("http-proxy-middleware");
var cors = require("cors");

const app = express();
const corsOptions = {
  //   origin: ["http://localhost:3000"],
  origin: true,
  credentials: true,
};
app.use(cors(corsOptions));

const proxyMiddleware = createProxyMiddleware("/", {
  target: "https://....api origin.....com",
  changeOrigin: true,
});

app.use(proxyMiddleware);

app.listen(3001, () => {
  console.log("proxy is listening on port 3001");
});
  • 리액트 앱은 포트 3000에서 실행 중이며 프록시 서버는 포트 3001에서 실행 중임을 유의하십시오.
  • 요청에 credential을 사용하고 있기 때문에 앱 오리진도 화이트리스트로 설정해야 합니다.그렇지 않으면 "Access-Control-Allow-Origin"을 "*"로 설정하여 브라우저 보안 오류가 발생합니다.

내 프록시를 통해 샘플 로그인 게시 요청에 응답:

      axios.post("http://localhost:3001/Login", dataToPost, { withCredentials: true })
      .then((res) => {
        if (res.status === 200) {
          //all cookies are set in you're browser
          console.log(res);
        }
      })
      .catch((err) => {
        console.log(err);
      });

서드파티 api 가져오기 등의 작업을 수행하려고 할 때 클라이언트 측에서 CORS 오류가 발생할 경우 다음 확장을 사용해 보십시오.

CORS 허용: 접근통제-허용-발신지

크롬의 경우: https://chrome.google.com/webstore/detail/allow-cors-access-control/lhobafahddgcelffkeicbaginigeejlf

Mozilla의 경우: https://addons.mozilla.org/pt-BR/firefox/addon/access-control-allow-origin/

@Nahush가 이미 지적한 바와 같이 이것은 실제로는 서버의 문제이며 클라이언트 측에서 처리할 필요가 없습니다.에서는, 「아니다」의 합니다.Access-Control-Allow-Origin:레퍼런스 - https://www.w3.org/wiki/CORS_Enabled#How_can_I_participate.3F

가 「이러다」, 「이러다」를 사용하고 있는 는, 할 수 있는 방법을 .express를 참조할 수 있습니다.를 위해 Express CORS 미들웨어를 사용하는 것은 2라인 코드 솔루션입니다.

다음을 사용하여 설치 -

npm install -S cors

백엔드 앱에 다음 코드를 추가합니다.

import cors from 'cors';
app.use(cors());

다 했어요.

이 문제에 대처하기 위해 두 가지 솔루션을 사용했습니다.

  1. 「」를 사용합니다.http-proxy-middleware다만, 라이브러리 「https://youtu.be/4B5WgTiKIOY를 읽는 대신에, 다음의 비디오 순서를 실행해 주세요.(이 솔루션도 사용하는 경우는, 이 약점에 대해 언급했습니다)
  2. Firebase functions너무 복잡하지 않게 미들웨어를 만들 수 있습니다.자세한 내용은 이쪽도 알려드리겠습니다.

궁금한 점이 있으면 알려주세요.

언급URL : https://stackoverflow.com/questions/43462367/how-to-overcome-the-cors-issue-in-reactjs

반응형