카테고리 없음

[React.js] 네이버 검색 API 받아오기 - CORS 에러

sakuraop 2022. 10. 4. 17:20

서버나 axios에 대한 설명을 같이 하기에는 이해가 부족하고 인터넷에 이미 전문적이고도 쉽게 설명한 정보가 많기 때문에 일단 데이터를 받아오는 것만이 목표입니다.


1. 네이버 검색 API로 데이터를 받아오기 위해서 검색 예제를 복사해, server.js 파일을 만들어 코드를 붙여넣어주었습니다.
https://developers.naver.com/docs/serviceapi/search/blog/blog.md#%EA%B2%80%EC%83%89-api-%EB%B8%94%EB%A1%9C%EA%B7%B8-%EA%B2%80%EC%83%89-%EA%B5%AC%ED%98%84-%EC%98%88%EC%A0%9C

 

Node.js 

// 네이버 검색 API 예제 - 블로그 검색
var express = require('express');
var app = express();
var client_id = 'YOUR_CLIENT_ID';
var client_secret = 'YOUR_CLIENT_SECRET';
app.get('/search/blog', function (req, res) {
   var api_url = 'https://openapi.naver.com/v1/search/blog?query=' + encodeURI(req.query.query); // JSON 결과
//   var api_url = 'https://openapi.naver.com/v1/search/blog.xml?query=' + encodeURI(req.query.query); // XML 결과
   var request = require('request');
   var options = {
       url: api_url,
       headers: {'X-Naver-Client-Id':client_id, 'X-Naver-Client-Secret': client_secret}
    };
   request.get(options, function (error, response, body) {
     if (!error && response.statusCode == 200) {
       res.writeHead(200, {'Content-Type': 'text/json;charset=utf-8'});
       res.end(body);
     } else {
       res.status(response.statusCode).end();
       console.log('error = ' + response.statusCode);
     }
   });
 });
 app.listen(3000, function () {
   console.log('http://127.0.0.1:3000/search/blog?query=검색어 app listening on port 3000!');
 });

 

2. 코드에서 필요한 라이브러리인 express를 [$ npm i express]로 설치합니다.

 


 

3. 네번째, 다섯번째 줄을 보면 필요한 것은 client_id와 client_secret입니다.

https://developers.naver.com/docs/serviceapi/search/movie/movie.md

위 주소로 들어가서 등록을 하면 받아올 수 있는 키입니다.

애플리케이션 등록을 합니다.

웹서비스 URL은 localhost의 포트 주소로 만들 것입니다.

react는 포트가 3000에 연결되어 있으므로 4000으로 url을 설정했습니다.

 


 

4. client_id와 client_secret키 변수에 넣어주기

만들어진 id와 secret코드를 넣어주도록 합니다.

var express = require("express");
var app = express();
var client_id = "여기다가 client id";
var client_secret = "여기다가 client secret";

 


 

5. cors 에러 해결하기

app.get("/", function (req, res) {
    res.header("Access-Control-Allow-Origin", "*");
와 같이 express에서 헤더를 설정합니다.

"*"는 모든 주소를 허용하겠다는 의미이기 때문에 좋지 않다는 얘기를 봤지만,
"https://openapi.naver.com/" 을 넣어주면 cors에러가 발생했기 때문에 "*"로 했습니다.
일단 구현이 목표이기 때문에 원인은 나중에 알아보기로 합니다.(...)
app.get("/", function (req, res) {
    res.header("Access-Control-Allow-Origin", "*");

    var api_url = `https://openapi.naver.com/v1/search/movie.json?query=%EC%A3%BC%EC%8B%9D&display=10&start=1&genre=1`; // 예시 url은 블로그 검색이었으므로, 영화 검색 query로 바꾸어줍니다.
 
    var request = require("request");
    var options = {
        url: api_url,
        headers: {
            "X-Naver-Client-Id": client_id,
            "X-Naver-Client-Secret": client_secret,
        },
    };

이것으로 cors 에러는 해결이 됩니다.

 


 

6. port 주소 4000으로 변경하기

app.listen(4000, function () {
    console.log("API CORS정책을 따르기 위한 서버 app listening on port 4000!");
});

네이버 api를 등록할 때 url과 동일하게 port를 4000으로 바꾸어줍니다.

 

http://localhost:4000/ 주소로 이동해보면 다음과 같이 출력됩니다.


 

7. 프론트에서 axios로 get 데이터 요청하기

 

NAVERDATA.js 파일을 만들어주었습니다.

axios를 설치해줍니다. 명령어는 [$ npm i axios] 입니다.

import axios from "axios";
import { useEffect, useState } from "react";

const NAVERMOVIEDATA = () => {
    const [itm, setItm] = useState();

    useEffect(() => {
        const url = "http://localhost:4000/"// localhost:4000에서 데이터를 받아올 것이니다.

        const getNaverMovie = async () => {
            const res = await axios.get(url); // async await 비동기 방식을 이용해 데이터를 받아옵니다.
            console.log(res.data.items, "네이버영화 검색결과 데이터");

            const NAVERMOVIES = res.data.items.map((it) => { // title, link, image를 받아올 것입니다.
                return
                    title: it.title,
                    link: it.link,
                    image: it.image,
                };
            });
            setItm(NAVERMOVIES);
        };
        getNaverMovie();
    }, []);

    return itm; // useState를 이용해 itm 에 저장한 데이터를 반환합니다.
};

export { NAVERMOVIEDATA }; // 함수를 내보냅니다.

이 단계에서 console.log()로 결과를 출력할 수 있습니다.

            const NAVERMOVIES = res.data.items.map((it) => {
                return {
                    title: it.title,
                    link: it.link,
                    image: it.image,
                };
            });
 
콜솔 창에는 출력할 수 있지만 react에서는 object 객체 자체를 렌더링 할 수 없습니다.
에러 :오브젝트는 리액의 자식으로 이용할 수 없습니다.
 
Unhandled Runtime Error
Error: Objects are not valid as a React child (found: object with keys {}). If you meant to render a collection of children, use an array instead.

 


 

8. 데이터를 나타내기 위해 map으로 렌더링하도록 합니다. 

우선 App.js에서 데이터를 담은 함수를 import합니다.

import { NAVERMOVIEDATA } from "./data/NAVERDATA";

const App = () => {
    const NAVERMOVIE = NAVERMOVIEDATA();


 

9. 데이터를 props로 그리고자 하는 컴포넌트에 전달합니다.

                                <Main NAVERMOVIE={NAVERMOVIE} />

 


 

10. Main.js 컴포넌트에서 map함수로 받아온 데이터를 html로 만듭니다.

const Main = ({ BOXDATA, NAVERMOVIE }) => {
    return (
        <main>
            <section className="MainVisual">
                <div className="container">
                    <h2>박스오피스</h2>

                    {NAVERMOVIE.map((el, idx) => {
                        return (
                            <ul key={idx}>
                                <li>{el.title}</li>
                                <li>{el.link}</li>
                                <li>{el.image}</li>
                            </ul>
                        );
                    })}

데이터가 받아와지고 화면에 렌더링까지 됐습니다.