使用 docker-compose 从容器获取图像时出现 CORS 错误

问题描述 投票:0回答:1

我有一个 NextJS 前端博客应用程序,可以从单独的动画 API 检索图像和视频。当这一切都在本地运行时(前端博客位于 localhost:3000,动画 API 位于 localhost:8001),一切都会按预期工作,并且图像(从动画 API 获得)会被渲染。

当我将应用程序容器化并使用 docker-compose 时,就会出现问题。这是我的

compose.yaml
文件:

version: '3.8'
services:
  blog-app:
    build:
      context: . # <-- ENSURES REBUILD EVERY TIME
      dockerfile: Dockerfile
    environment:
      - ANIMATION_URL=http://animation-app:5000 # <-- RELEVANT
      - MARKDOWN_URL=http://markdown-app:5000
      - AVATARS_URL=https://avatars.githubusercontent.com
  nginx:
    image: jdev9487/blog-proxy-server:latest
    depends_on:
      - blog-app
    ports:
      - '443:443'
      - '80:80'
    volumes:
      - ./.nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
  animation-app: # <-- RELEVANT
    image: jdev9487/math-blog-animations:latest
    ports:
      - '8001:5000'
  markdown-app:
    image: jdev9487/blog-markdown:latest
    ports:
      - '8000:5000'

博客应用中相关的

fetch
调用是这样的:

"use client";

import Link from "next/link";
import Avatar from '@mui/material/Avatar';
import { PostMetadata } from "./postMetadata";
import ShareIcon from '@mui/icons-material/Share';
import { useEffect, useState } from "react";

export default function PostPreview(props: PostMetadata) {

    const [img, setImg] = useState('')
    useEffect(() => {
        const fetchData = async () => {
            const url = `${props.animationUrl}/thumbnails/${props.featuredAnimation}`;
// props.animationUrl gets populated from env variables in compose.yaml
            var res = await fetch(url);
            var blob = await res.blob();
            var blobUrl = URL.createObjectURL(blob);
            setImg(blobUrl);
        }
        fetchData();
    }, []);

    return (
        <div className="flex flex-row border border-background-secondary shadow min-h-80">
            <div className="flex basis-1/2">
                <img id="thumbnail" className="object-cover" src={img} />

动画 API 是一个 Python Flask 应用程序:

from flask import Flask
from flask import send_file
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.get("/animations/<slug>")
def animation(slug):
    filename = f'output/{slug}.mp4'
    return send_file(filename, mimetype='image/mp4')

@app.get("/thumbnails/<slug>") # <-- this is the endpoint being called
def thumbnail(slug):
    filename = f'output/{slug}.png'
    return send_file(filename, mimetype='image/png')

if __name__ == "__main__":
    app.run()

我现在遇到了 CORS 问题,这在某种程度上是可以理解的。与非容器化设置相比,API 调用现在尝试从不同的来源获取图像;这是博客应用程序浏览器中的控制台错误:

跨域请求被阻止:同源策略不允许读取 远程资源位于 http://animation-app:5000/thumbnails/completingTheSquare。 (原因: CORS 请求未成功)。状态码:(空)

我的问题是:为什么我会遇到 CORS 问题?

我已将 CORS 包含在动画 API 中,因此根据 docs,预计所有域和所有路由都将被允许。我不确定是否需要修改客户端调用 API 的获取参数...

我对 CORS 没有足够的了解,无法理解这里的问题所在。

next.js docker-compose fetch-api flask-cors
1个回答
0
投票

正如 @DavidMaze 和 @willwrighteng 所强调的,通过使用现有的 nginx 容器 (

jdev9487/blog-proxy-server:latest
) 作为反向代理服务器解决了该问题。

所有 CORS 均已从动画 API 中删除。额外的配置被放置在 nginx 服务器的

default.conf
中:

...

    location /animation/ {
        proxy_pass http://animation-app:5000/;
    }

...

compose.yaml
文件已编辑:

version: '3.8'
services:
  blog-app:
    build:
      context: .
      dockerfile: Dockerfile
    environment:
      - ANIMATION_URL=/animation

现在

fetch
对动画应用程序的调用首先转到
localhost/animation
,这是相同的起源,因此没有 CORS 问题。

© www.soinside.com 2019 - 2024. All rights reserved.