LoginSignup
weweweok
@weweweok

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

deno freshにおいてfetch APIでbase64文字列を受け取ることができない

解決したいこと

fetchAPIを使って、サーバ側に画像を送信し -> それを加工して、base64文字列でResponse -> base64文字列よりクライアント側にその画像を表示するアプリを作っています。

クライアントからの画像の送信、サーバ側で画像を加工してbase64文字列にするところまではできているのですが、レスポンスを返すときにクライアントのfetchで以下のようなエラーが出ます。

サーバ側からクライアント側にbase64文字列を返せるようにすることが目的です。

例)
Ruby on RailsでQiitaのようなWebアプリをつくっています。
記事を投稿する機能の実装中にエラーが発生しました。
解決方法を教えて下さい。

発生している問題・エラー

エラー箇所
image.png
image.png

該当するソースコード

クライアント側のコード(該当箇所のみ)

    e.preventDefault();
    const imageElement = document.getElementById(
      "upload-form",
    ) as HTMLFormElement;
    const image = imageElement.files[0];

    const formData = new FormData();
    formData.append("files", image);
    const response = await fetch("http://127.0.0.1:8001/files/", {
      method: "POST",
      body: formData,
      mode: "no-cors",
    });
    console.log(await response.json());
   

サーバ側のコード(fastAPIを使用)

from typing import Annotated
from creategif import CreateAsciiArt

from fastapi import FastAPI, File, Request, status

from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse

app = FastAPI()

@app.exception_handler(RequestValidationError)
async def handler(request: Request, exc: RequestValidationError):
    print(exc)
    return JSONResponse(content={}, status_code=status.HTTP_422_UNPROCESSABLE_ENTITY)


@app.post("/files/")
async def create_files(files: Annotated[bytes, File()]):
    # ↓画像を加工して、base64文字列に保存
    output = CreateAsciiArt().create_ascii_art_from_binary(files)
    return {"base64": output}

自分で試したこと

postman(APIの検証・テストツール)の結果
image.png

0

2Answer

「エラー箇所」の画像のコードと「クライアント側のコード(該当箇所のみ)」のコードと違うのですがどっちがホントですか?

要求先 http://127.0.0.1:8001/files/ は同一ドメインですか? 異なるドメインの場合サーバー側で CORS 対応はされてますか? mode: "no-cors" を付与した意図は何ですか?


【追記】

上の質問に対する返事がないので想像ですが・・・

クロスドメインに対する要求になっているが、サーバー側は CORS 対応してないので、fetch で mode: "no-cors" を設定すれば CORS 関連の問題は回避できると思っていませんか?

もしそうだとすると、そういうことはできないので、サーバー側で CORS 対応が必要です。そして mode: "cors" (デフォルト) に設定する必要があります。

mode: "no-cors" というのは CORS 対応しないという意味のようです。

クロスドメインに対する fetch で mode: "no-cors" とした場合、たとえサーバー側で CORS 対応がしてあったとしても、ブラウザ側では CORS 対応してくれません。

下の画像は自分の開発環境の Windows 10 の Chrome 119.0.6045.160 で、CORS 対応してあるサーバーに要求を出して応答を見たものです。違いが判るでしょうか?

mode: "no-cors"

fetch.png

mode: "cors" (デフォルト)

fetch2.png

1Like

Comments

  1. @weweweok

    Questioner

    ありがとうございます。no-corsにした理由は特にないです。fetch APIのモードをcorsにしてfastAPI側において、すべてのオリジンを許可するように設定したところうまく動きました。

    ありがとうございます。

Comments

  1. @weweweok

    Questioner

    意図はなく単なる記述ミスです。このように記述しても同じエラーが出力されました。

    const response = await fetch("http://127.0.0.1:8001/files/", {
          method: "POST",
          body: formData,
          mode: "no-cors",
        });
        console.log(await response.json());
    

Your answer might help someone💌