3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

サーバーサイドからのリクエストでCORSエラーを回避する方法

Last updated at Posted at 2024-08-16

はじめに

ウェブ開発において、異なるオリジン間でのデータのやり取りは一般的ですが、クロスオリジンリクエストに関連するCORS(クロスオリジンリソース共有)エラーに悩まされることがあります。この記事では、Next.jsを用いてサーバーサイドからリクエストを送ることでCORSエラーを回避する方法を紹介します。

CORSとは

CORS(クロスオリジンリソース共有)は、ウェブブラウザが異なるオリジン(ドメイン、ポート、またはプロトコル)からのリクエストを制限するセキュリティ機能です。クライアントサイドからサーバーにリクエストを送信する際、ChromeなどのブラウザはサーバーからのレスポンスにAccess-Control-Allow-Originヘッダーが含まれているかどうかをチェックします。もし、このヘッダーが存在しないか、リクエスト元のオリジンが許可されていない場合、CORSエラーが発生し、リクエストはブロックされます。

参考にしたもの

ブラウザからサーバーにアクセスすると

ステップ 1: クライアント(ブラウザ)リクエスト

ブラウザがクロスオリジンリクエストを行うと、ブラウザはOriginヘッダーを現在のオリジン(スキーム、ホスト、ポート)とともに追加します。

ステップ 2: サーバーレスポンス

サーバーがこのヘッダーを確認し、アクセスを許可すると、リクエスト元のオリジンを指定するAccess-Control-Allow-Originヘッダーをレスポンスに追加します(または、任意のオリジンを許可する場合は*)。

ステップ 3: ブラウザがレスポンスを受信する

ブラウザは、適切なAccess-Control-Allow-Originヘッダーを含むこのレスポンスを確認すると、レスポンスデータをクライアントサイトと共有します。

問題が発生した事例

今回は、環境省のウェブサイトからCSVデータを取得しようとした際に、クライアントサイドでCORSエラーが発生しました。おそらく、環境省のサーバーがAccess-Control-Allow-Originヘッダーを含めていなかったため、ブラウザがリクエストを拒否したと思われます。

環境省 暑さ指数(WBGT)予測値等 電子情報提供サービス

対応方法

Next.jsのサーバーサイドから環境省のウェブサイトにリクエストすることにしました。Next.jsなどのサーバーサイド環境からリクエストを送る場合、ブラウザのCORSチェックが適用されません。これにより、環境省のサーバーがAccess-Control-Allow-Originヘッダーを含んでいなくても、問題なくデータを取得できます。

ファイル構成

my-next-app/
├── package.json
├── tsconfig.json
├── next.config.js
├── src/
│   ├── pages/
│   │   ├── index.tsx
│   │   └── api/
│   │       └── wbgt.ts //サーバーサイドからのリクエスト用ファイル
└── (その他の設定ファイルやディレクトリ)

サーバーサイドからのリクエスト

src/pages/api/wbgt.ts
import axios from 'axios'

export default async function handler(req: any, res: any) {
  const AREA_CODE = '44132' // 東京の地点コード

  try {
    const response = await axios.get(
      `https://www.wbgt.env.go.jp/prev15WG/dl/yohou_${AREA_CODE}.csv`,
    )
    const data = response.data

    res.status(200).json({ data })
  } catch (error) {
    console.error('CSVデータの取得に失敗しました', error)
    res.status(500).json({ error: 'CSVデータの取得に失敗しました' })
  }
}

参考 API Routeについて

クライアントサイドでの利用

src/pages/index.tsx
import { useEffect, useState } from 'react'
import axios from 'axios'

const Index = () => {
  const [data, setData] = useState(null)

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await axios.get('/api/wbgt')
        setData(response.data)
        console.log(data)  //コンソール画面に取得したdataを表示
      } catch (error) {
        console.error('データの取得に失敗しました', error)
      }
    }

    fetchData()
  }, [])

  return (
    <div>
      <h1>WBGTインデックス</h1>
    </div>
  )
}

export default Index

クライアントサイドでは、このAPIルートに対してリクエストを送信し、取得したコンソール画面に表示しています。

結論

ブラウザのCORS制約は、クライアントサイドのセキュリティを強化するための重要な機能ですが、開発中にエラーを引き起こすことがあります。Next.jsなどのサーバーサイドでのリクエストを利用することで、これらの制約を回避し、安全にデータを取得する方法を紹介しました。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?