테스트 사이트 - 개발 중인 베타 버전입니다

자바스크립트 예제

· 11개월 전 · 470 · 3

윈드서프 에디터를 활용해 만든

https://codeium.com/windsurf

 

자바스크립트 예제를 올리고 있습니다.
https://sir.kr/javascript/

 

my-ip 의 같은 경우 굉장히 쉽게 구현할 수 있습니다.

 

 

src/app/my-ip/route.js

 

[code]

'use client';

import { useState, useEffect } from 'react';

import Image from 'next/image';

 

const InfoItem = ({ label, value }) => (

  <div className="flex items-center p-4 bg-gray-50 rounded-lg hover:bg-gray-100 transition-colors">

    <span className="font-medium text-gray-600 w-24">{label}:</span>

    <span className="text-gray-800 ml-4">{value}</span>

  </div>

);

 

const LoadingSpinner = () => (

  <div className="flex justify-center items-center">

    <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"></div>

  </div>

);

 

const ErrorDisplay = ({ message }) => (

  <div className="flex items-center justify-center space-x-2 text-red-500">

    <svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">

      <path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clipRule="evenodd" />

    </svg>

    <span>{message}</span>

  </div>

);

 

const fetchIPInfo = async () => {

  const apis = [

    'https://ipapi.co/json/',

    'https://api.ipify.org?format=json'

  ];

 

  try {

    const responses = await Promise.any(

      apis.map(api =>

        fetch(api, {

          headers: {

            'Accept': 'application/json'

          }

        })

          .then(async res => {

            if (!res.ok) {

              throw new Error(`HTTP error! status: ${res.status}`);

            }

            const data = await res.json();

            return {

              success: true,

              data

            };

          })

          .catch(error => ({

            success: false,

            error: error.message

          }))

      )

    );

 

    if (!responses.success) {

      console.error('API 요청 실패:', responses.error);

      throw new Error('IP 정보를 가져오는데 실패했습니다');

    }

 

    const { data } = responses;

   

    // ipapi.co 응답 형식

    if (data.ip) {

      return {

        ip: data.ip,

        country: data.country_name,

        countryCode: data.country_code,

        region: data.region,

        city: data.city,

        timezone: data.timezone,

        isp: data.org,

        latitude: data.latitude,

        longitude: data.longitude

      };

    }

   

    // api.ipify.org 응답 형식

    return {

      ip: data.ip,

      country: 'N/A',

      countryCode: 'N/A',

      region: 'N/A',

      city: 'N/A',

      timezone: 'N/A',

      isp: 'N/A',

      latitude: 'N/A',

      longitude: 'N/A'

    };

  } catch (error) {

    console.error('IP 정보 가져오기 실패:', error);

    throw new Error('IP 정보를 가져오는데 실패했습니다');

  }

};

 

export default function MyIP() {

  const [ipInfo, setIpInfo] = useState(null);

  const [error, setError] = useState(null);

 

  useEffect(() => {

    const getIPInfo = async () => {

      try {

        const data = await fetchIPInfo();

        setIpInfo(data);

      } catch (error) {

        setError(error.message);

      }

    };

 

    getIPInfo();

  }, []);

 

  if (error) {

    return (

      <div className="min-h-screen p-4">

        <div className="max-w-2xl mx-auto bg-white rounded-xl shadow-md p-8">

          <ErrorDisplay message={error} />

        </div>

      </div>

    );

  }

 

  if (!ipInfo) {

    return (

      <div className="min-h-screen p-4">

        <div className="max-w-2xl mx-auto bg-white rounded-xl shadow-md p-8">

          <LoadingSpinner />

        </div>

      </div>

    );

  }

 

  return (

    <div className="min-h-screen p-4">

      <div className="max-w-2xl mx-auto bg-white rounded-xl shadow-md p-8">

        <div className="flex items-center justify-center mb-6">

          <h1 className="text-3xl font-bold text-gray-800">

            내 IP 확인

          </h1>

        </div>

       

        <div className="space-y-4">

          <InfoItem label="IP 주소" value={ipInfo.ip} />

          <InfoItem label="국가" value={`${ipInfo.country} (${ipInfo.countryCode})`} />

          <InfoItem label="지역" value={ipInfo.region} />

          <InfoItem label="도시" value={ipInfo.city} />

          <InfoItem label="시간대" value={ipInfo.timezone} />

          <InfoItem label="ISP" value={ipInfo.isp} />

          <InfoItem label="위치" value={`${ipInfo.latitude}, ${ipInfo.longitude}`} />

        </div>

 

        <div className="mt-6 text-center">

          <a

            href={`https://www.google.com/maps?q=${ipInfo.latitude},${ipInfo.longitude}`}

            target="_blank"

            rel="noopener noreferrer"

            className="inline-flex items-center text-blue-500 hover:text-blue-700 transition-colors"

          >

            <svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 mr-2" viewBox="0 0 20 20" fill="currentColor">

              <path fillRule="evenodd" d="M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z" clipRule="evenodd" />

            </svg>

            구글 지도에서 보기

          </a>

        </div>

      </div>

    </div>

  );

}

[/code]

 

 

 

 

 

댓글 작성

댓글을 작성하시려면 로그인이 필요합니다.

로그인하기

댓글 3개

11개월 전

대개는 ISP업체 정도 추적이 되는데~

 

조금 더 세밀하군요.

 

기억하여, 공유하고 잘 사용하겠습니다.

 

.     https://glitter.my/ip

 

~감사합니다.

11개월 전

오 이런겄도 있군요.

11개월 전

대신 구글지도는 꽝이네요.ㅋㅋ

게시글 목록

번호 제목
12
11
7
6
4
3
2
1