본문 바로가기

programming/React

[Next.js] Google Map Distance Matrix API 프론트단에서 사용하기

목표 : 출발지 주소 ~ 목적지 주소 사이의 거리 구하기

 

이슈 : 클라이언트 사이드에서 fetch 요청을 하면, CORS 에러가 발생

클라이언트 사이드에서 fetch 요청을 하는 경우 참고 코드

 

How to Use Google Maps Distance Matrix API in React.js

React.js is a popular JavaScript library for building user interfaces, and integrating Google Maps services can add powerful location-based…

medium.com

 

 

 

원인 : distancematrix API 는 서버사이드에서 요청을 해야한다

반면에 geocode API 는 클라이언트 사이드에서 요청을 해도 잘만 나온다

 

 

Geocoding API 사용 코드

// Google Maps API를 사용하여 Reverse Geocoding을 통해 장소 이름 가져오기
  const response = await axios.get("https://maps.googleapis.com/maps/api/geocode/json", {
    params: {
      latlng: `${latitude},${longitude}`,
      key: `${process.env.NEXT_PUBLIC_GOOGLE_MAP_API_KEY}`,
    },
  });

 

 => 정상적인 응답을 잘 받아온다 

 

 

Distance Matrix API 사용 코드

const response = await axios.get("https://maps.googleapis.com/maps/api/distancematrix/json", {
      params: {
        origins: origin,
        destinations: destination,
        mode: "transit",
        key: `${process.env.NEXT_PUBLIC_GOOGLE_MAP_API_KEY}`,
      },
    });

 

=> CORS 에러 발생한다

 

 

관련 내용 참고

 

CORS error · Issue #59 · googlemaps/google-maps-services-js

CORS error with a distancematrix request. But geocoder request works fine. What am I missing? Fetch API cannot load https://maps.googleapis.com/maps/api/distancematrix/json?destinations=New%2…%20La...

github.com

 

따봉 많이 받으신 분의 코멘트 요약해보면, API 문서에 어디에도 서버사이드에서만 작동한다는 말이 없는데, distancematrix 는 서버사이드로 요청해야한다고 해서 트러블 슈팅에 시간을 많이 소요했다. 결론은 클라이언트 사이드에서 distance matrix 를 구하려면 Javascript API 를 사용해야한다.

 

 

해결방안 : Next.js 의 api/route 를 사용

브라우저에서 바로 요청하지 않고, Next 서버에서 요청 후 응답을 리턴하는 거로 변경

 

1. /app/api/googlemaps/route.ts 파일생성

import { NextResponse } from "next/server";
import axios from "axios";

export async function GET(request: Request) {
  const url = new URL(request.url);
  const origins = url.searchParams.get("origins");
  const destinations = url.searchParams.get("destinations");

  try {
    const response = await axios.get("https://maps.googleapis.com/maps/api/distancematrix/json", {
      params: {
        origins: `${origins}`,
        destinations: `${destinations}`,
        mode: "transit",
        key: {YOUR_API_KEY},
      },
    });
    
    return NextResponse.json({ distance: response?.data?.rows[0]?.elements[0]?.distance?.text || "" });
  } catch (error) {
    console.error("Failed to fetch distance:", error);
    return NextResponse.json({ distance: "Unknwon distance" });
  }
}

 

2. 컴포넌트 단에서 Next 서버로 fetch 요청

const origins = "서울특별시 강남구 선릉로 551";
const destinations = store.address

const result = await fetch(`/api/googlemaps?origins=${origins}&destinations=${destinations}`);
const data = await result.json();

console.log('distance', data.distance)

 

CORS 해결...!