简体   繁体   English

使用 next/image 从 Firebase 存储中获取图像会导致 400 状态代码

[英]Fetching an image from Firebase storage using next/image results in a 400 status code

I am using the NextJS Image component like this:我正在像这样使用 NextJS Image 组件:

<Image src="https://firebasestorage.googleapis.com/v0/b/africatech-7cf1b.appspot.com/o/images%2F1606851317444_impact-logo-sq-Owen-Hancock.png?alt=media&token=35afb1d8-4ab8-4f58-81b4-dd25e1f5f3eb" layout="fill" />

Locally it works and in the DOM it looks like this:它在本地有效,在 DOM 中看起来像这样:

<img alt="Company logo" src="/_next/image?url=https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fafricatech-7cf1b.appspot.com%2Fo%2Fimages%252F1606851317444_impact-logo-sq-Owen-Hancock.png%3Falt%3Dmedia%26token%3D35afb1d8-4ab8-4f58-81b4-dd25e1f5f3eb&amp;w=3840&amp;q=75" decoding="async" sizes="(max-width: 640px) 640px, (max-width: 750px) 750px, (max-width: 828px) 828px, (max-width: 1080px) 1080px, (max-width: 1200px) 1200px, (max-width: 1920px) 1920px, (max-width: 2048px) 2048px, 3840px" srcset="/_next/image?url=https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fafricatech-7cf1b.appspot.com%2Fo%2Fimages%252F1606851317444_impact-logo-sq-Owen-Hancock.png%3Falt%3Dmedia%26token%3D35afb1d8-4ab8-4f58-81b4-dd25e1f5f3eb&amp;w=640&amp;q=75 640w, /_next/image?url=https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fafricatech-7cf1b.appspot.com%2Fo%2Fimages%252F1606851317444_impact-logo-sq-Owen-Hancock.png%3Falt%3Dmedia%26token%3D35afb1d8-4ab8-4f58-81b4-dd25e1f5f3eb&amp;w=750&amp;q=75 750w, /_next/image?url=https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fafricatech-7cf1b.appspot.com%2Fo%2Fimages%252F1606851317444_impact-logo-sq-Owen-Hancock.png%3Falt%3Dmedia%26token%3D35afb1d8-4ab8-4f58-81b4-dd25e1f5f3eb&amp;w=828&amp;q=75 828w, /_next/image?url=https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fafricatech-7cf1b.appspot.com%2Fo%2Fimages%252F1606851317444_impact-logo-sq-Owen-Hancock.png%3Falt%3Dmedia%26token%3D35afb1d8-4ab8-4f58-81b4-dd25e1f5f3eb&amp;w=1080&amp;q=75 1080w, /_next/image?url=https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fafricatech-7cf1b.appspot.com%2Fo%2Fimages%252F1606851317444_impact-logo-sq-Owen-Hancock.png%3Falt%3Dmedia%26token%3D35afb1d8-4ab8-4f58-81b4-dd25e1f5f3eb&amp;w=1200&amp;q=75 1200w, /_next/image?url=https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fafricatech-7cf1b.appspot.com%2Fo%2Fimages%252F1606851317444_impact-logo-sq-Owen-Hancock.png%3Falt%3Dmedia%26token%3D35afb1d8-4ab8-4f58-81b4-dd25e1f5f3eb&amp;w=1920&amp;q=75 1920w, /_next/image?url=https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fafricatech-7cf1b.appspot.com%2Fo%2Fimages%252F1606851317444_impact-logo-sq-Owen-Hancock.png%3Falt%3Dmedia%26token%3D35afb1d8-4ab8-4f58-81b4-dd25e1f5f3eb&amp;w=2048&amp;q=75 2048w, /_next/image?url=https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fafricatech-7cf1b.appspot.com%2Fo%2Fimages%252F1606851317444_impact-logo-sq-Owen-Hancock.png%3Falt%3Dmedia%26token%3D35afb1d8-4ab8-4f58-81b4-dd25e1f5f3eb&amp;w=3840&amp;q=75 3840w" style="visibility: visible; position: absolute; top: 0px; left: 0px; bottom: 0px; right: 0px; box-sizing: border-box; padding: 0px; border: none; margin: auto; display: block; width: 0px; height: 0px; min-width: 100%; max-width: 100%; min-height: 100%; max-height: 100%;">

However, on production it does not load the image.但是,在生产中它不会加载图像。 There is a 400 message:有一条400消息:

GET https://launchafrica.io/_next/image?url=https%3A%2F%2Ffirebasestorage.googleapis.com%2Fv0%2Fb%2Fafricatech-7cf1b.appspot.com%2Fo%2Fimages%252F1606851317444_impact-logo-sq-Owen-Hancock.png%3Falt%3Dmedia%26token%3D35afb1d8-4ab8-4f58-81b4-dd25e1f5f3eb&w=1920&q=75 400

Which seems to be because of: "url" parameter is not allowed这似乎是因为:不允许使用“url”参数

In my next.config.js I have this configured:在我的next.config.js ,我配置了这个:

images: { domains: ['firebasestorage.googleapis.com'], },

Could someone assist me in figuring out how to use next/image with a Firebase storage hosted image in production?有人可以帮我弄清楚如何在生产中使用next/image和 Firebase 存储托管图像吗? As locally it loads fine.在本地它加载正常。

Any chance you're hosting this on Firebase Hosting as well?你有没有机会在 Firebase Hosting 上托管这个? I had this issue, and I realized that I had to import the next.config.js into the configuration while initializing NextJS:我遇到了这个问题,我意识到我必须在初始化 NextJS 时将 next.config.js 导入配置:

const customNextConfig = require('./next.config');

const server = next({
  dev: isDev,
  conf: customNextConfig,
});

...

You need to add the below code on your next.config.js:您需要在 next.config.js 中添加以下代码:

...
images: {
    domains: ['firebasestorage.googleapis.com'],
},
...

I'm late for the topic, but hope my answer will help someone else.我迟到了这个话题,但希望我的回答能帮助别人。

Adding the domain's config into the next.config.js is not enough, you need to make sure that your "next" instance grabs that config.将域的配置添加到 next.config.js 中是不够的,您需要确保您的“下一个”实例获取该配置。

So in my case, what I did to make it work is:因此,就我而言,我为使其发挥作用所做的工作是:

Before

const nextjsDistDir = join("src", require("./src/next.config.js").distDir);
const nextjsServer = next({
  dev: isDev,
  conf: {
    distDir: nextjsDistDir
  }
});

After

const nextjsDistDir = join("src", require("./src/next.config.js").distDir);
const nextjsServer = next({
  dev: isDev,
  conf: {
    distDir: nextjsDistDir,
    images: {
      domains: ['firebasestorage.googleapis.com'],
    }
  }
});

Leaving this here for posterity (as of 2021/12/21): this appears to be because NextJS (when started using npm start) doesn't actually use the next.config.js file.将其留给后代(截至 2021 年 12 月 21 日):这似乎是因为 NextJS(开始使用 npm 启动时)实际上并未使用 next.config.js 文件。 Looking at https://github.com/vercel/next.js/blob/canary/packages/next/cli/next-start.ts#L61 , only the project directory, hostname and port are passed in to https://github.com/vercel/next.js/blob/canary/packages/next/server/lib/start-server.ts#L44 .查看https://github.com/vercel/next.js/blob/canary/packages/next/cli/next-start.ts#L61 ,只有项目目录、主机名和端口传入https:// github.com/vercel/next.js/blob/canary/packages/next/server/lib/start-server.ts#L44 Because the conf parameter is not passed in, the images.domains is missing.因为没有传入conf参数,所以缺少images.domains。

I ended up having to write my own (based on https://github.com/vercel/next.js/blob/canary/examples/custom-server-express/server.js ):我最终不得不自己编写(基于https://github.com/vercel/next.js/blob/canary/examples/custom-server-express/server.js ):

const port = parseInt(process.env.PORT, 10) || 5000
const listen = process.env.LISTEN_INTERFACE || '127.0.0.1';
const dev = process.env.NODE_ENV !== 'production';
const app = next({
    dev: dev,
    customServer: false,
    hostname: process.env.HOSTNAME || 'localhost',
    conf: {
        images: {
            domains: [process.env.NEXT_PUBLIC_IMAGE_DOMAIN]
        },
        trailingSlash: true,
    poweredByHeader: false
    }
})
const handle = app.getRequestHandler()

app.prepare().then(() => {
  const container = express();
    
  container.all('*', (req, res) => {
    return handle(req, res)
  })
    
    const server = http.createServer(container);
  server.listen(port, listen);
});

my problem solved with我的问题解决了

images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: '**',
      },
    ],
  },

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM