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

자바스크립트 예제

· 11개월 전 · 467 · 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개월 전

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

게시글 목록

번호 제목
427
424
421
416
411
408
401
400
393
390
389
386
382
380
378
367
361
358
354
347
339
337
336
329
328
318
316
315
311
302