对于生产部署,我们有一个由 3 台 Linux 机器组成的网络。其中两个用于部署,一个是 nginx 代理。
对于开发部署,我们有一台单独的 Linux 机器。
在前端(这是一个 nextjs 框架)内部,设置了一个 http-proxy-middleware 用于解析浏览器的 cors 请求。
这是http-proxy-middleware的代码:
import { API_URL } from "../../../config/";
import { createProxyMiddleware } from "http-proxy-middleware";
// Create proxy instance outside of request handler function to avoid unnecessary re-creation
const apiProxy = createProxyMiddleware({
target: `${API_URL}`,
changeOrigin: true,
pathRewrite: { [`^/api/proxy`]: "" },
secure: false,
});
export default function handler(req, res) {
console.log(
`Method: ${req.method} URL: ${req.url} Status Code: ${res.statusCode}`
);
apiProxy(req, res, (result) => {
if (result instanceof Error) {
throw result;
}
throw new Error(
`Request '${req.url}' is not proxied! We should never reach here!`
);
});
}
export const config = { api: { externalResolver: true, bodyParser: false } };
为了获取图像,我们只需在 next/image 组件的 src 属性中提供图像 url。像这样:
<Image
src={currentImage.imageurl}
alt={currentImage.imageurl}
layout="fill"
className={styles.imageSize} />
这是 next.config.js 文件:
module.exports = {
reactStrictMode: true,
images: {
domains: ["exam105.s3.amazonaws.com"],
},
async headers() {
return [
{
source: "/(.*)",
headers,
},
];
},
};
正如您在上面的 next.config.js 文件中看到的,我也添加了图像的域。我还取消了 dockerfile 中这一行的注释,以上传 next.config.js 文件中的更改:COPY --from=builder /app/next.config.js ./
这就是为什么当前端部署在开发服务器上时,将获取图像并在浏览器上显示。但是,当前端部署在生产环境中时,不会显示图像,而是会弹出错误:
在浏览器上,它给出500 Internal Server Error
。
这是 nginx 日志中出现的错误:
"GET /_next/image?url=https%3A%2F%2Fexam105.s3.amazonaws.com%2Fimage.jpg&w=128&q=75 HTTP/1.1" 500 32 "https://exam105.com/search/6176cdfe27612732e98a25d9/6176cdfe27612732e98a25d6" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62"
前端日志打印此错误:
FetchError: request to https://exam105.s3.amazonaws.com/image.JPG failed, reason: getaddrinfo EAI_AGAIN exam105.s3.amazonaws.com
at ClientRequest.<anonymous> (/app/node_modules/node-fetch/lib/index.js:1461:11)
at ClientRequest.emit (node:events:390:28)
at TLSSocket.socketErrorListener (node:_http_client:447:9)
at TLSSocket.emit (node:events:390:28)
at emitErrorNT (node:internal/streams/destroy:157:8)
at emitErrorCloseNT (node:internal/streams/destroy:122:3)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
type: 'system',
errno: 'EAI_AGAIN',
code: 'EAI_AGAIN'
}
正如我们从 nginx 日志中的错误中看到的,图像 URL 是用某些字符进行编码的,在我看来这可能就是问题所在。当我通过单击浏览器中损坏的图像进入检查元素时,该网址也可见。前端正在发送编码的 url,但未解码,因此抛出错误。我们如何删除下一个/图像组件的编码?或者,如果无法阻止编码,我们如何在架构的上下文中对其进行解码?因为我尝试更换<Image.../>
with <img.../>
标签和图像也开始显示在生产环境中部署的前端上。这次当我在浏览器中检查图像时,没有在 URL 中看到任何编码。因此 next/image 组件正在执行编码,但在部署到生产服务器上时它不会被解码,但是当它部署在开发服务器上时,它会被解码并且也可以使用 next/image 组件看到图像。
我希望你能理解这个问题。
如果有不清楚的地方,请发表评论。谢谢。