10
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?

More than 1 year has passed since last update.

Nuxt3でproxyして外部APIにアクセスするには

Posted at

βまでの方法

Nuxt3で 外部APIにアクセスしたい場合、
βでは nuxt.config.ts に↓の様に書いてvite経由でいけたのですが…

vite: {
    server: {
      proxy: {
        "/api/": {
          target: process.env.PROXY_API_URL,
          secure: false
        }
      }
    }
  }

諸々の議論があったようで本リリースでは使えなくなっています。

また、@nuxtjs/proxy の対応もまだ(renovate/nuxt-3.xというブランチは存在)なので
現状では自分で server を書かないとだめそうです。

本リリース以降の方法

/api のアクセスをproxyするとします。

ディレクトリとファイルの作成

.
├── server
│   ├── api
│   │   ├── [...].ts

この [...].ts というファイル名がポイントで /api/* の * を全て受け入れてくれます。
公式ドキュメント Catch-all Route

[...].ts の中身(JWTサンプル)

import {defineEventHandler, getHeaders, getMethod, getQuery, readBody} from "h3";

const config = useRuntimeConfig()
const baseURL = config.public.apiUrl

// noinspection JSUnusedGlobalSymbols
export default defineEventHandler(async (event) => {
    const method = getMethod(event)
    const params = getQuery(event)

    const headers = getHeaders(event)

    // tokenをクッキーに保存するとした場合
    const authorization = headers.Authorization || getCookie(event, 'auth.token')

    // /api -> / にプロキシしたいので replaceで消す
    const url = (event.node.req.url as string).replace(/^\/api/, '')

    const body = method === "GET" ? undefined : await readBody(event)

    return await $fetch(url, {
        headers: {
            "Content-Type": headers["content-type"] as string,
            Authorization: authorization as string,
        },
        baseURL,
        method,
        params,
        body,
    })
})

自己証明書を利用する場合

.env に以下を追加してください。

NODE_TLS_REJECT_UNAUTHORIZED=0

(これを思い出して調べるの意外と時間がかかった…:no_mouth:
fetchAPIをつかってるはずなのでagentを渡せば…と思いきや、
FetchOptionsにagentが渡せそうにないのでこの方法で。

interface FetchOptions<R extends ResponseType = ResponseType> extends Omit<RequestInit, "body"> {
    baseURL?: string;
    body?: RequestInit["body"] | Record<string, any>;
    params?: SearchParameters;
    query?: SearchParameters;
    parseResponse?: (responseText: string) => any;
    responseType?: R;
    response?: boolean;
    retry?: number | false;
    onRequest?(context: FetchContext): Promise<void> | void;
    onRequestError?(context: FetchContext & {
        error: Error;
    }): Promise<void> | void;
    onResponse?(context: FetchContext & {
        response: FetchResponse<R>;
    }): Promise<void> | void;
    onResponseError?(context: FetchContext & {
        response: FetchResponse<R>;
    }): Promise<void> | void;
}
10
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
10
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?