最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - SvelteKit build (w adapter-node) 404 on newly created static files - Stack Overflow

programmeradmin1浏览0评论

Using @sveltejs/adapter-node: 1.0.0-next.61 and @sveltejs/kit: ^1.0.0-next.225

The following issue occurs only on the build version of the app, and not on the dev server, on which it doesn't occur.

When uploading a new file, my app keeps returning 404 regarding those newly created files as though the app is blind to those. Interestingly enough, said images are found when restarting the server.

The creation request succeeds:

The file is correctly created on the filesystem and should be loaded by the page as seen in the json response which lists all files to be loaded on the page:

However, when attempting to fetch the file, the server responds with a 404 although the path to it is correct:

Using @sveltejs/adapter-node: 1.0.0-next.61 and @sveltejs/kit: ^1.0.0-next.225

The following issue occurs only on the build version of the app, and not on the dev server, on which it doesn't occur.

When uploading a new file, my app keeps returning 404 regarding those newly created files as though the app is blind to those. Interestingly enough, said images are found when restarting the server.

The creation request succeeds:

The file is correctly created on the filesystem and should be loaded by the page as seen in the json response which lists all files to be loaded on the page:

However, when attempting to fetch the file, the server responds with a 404 although the path to it is correct:

Share Improve this question asked Mar 22, 2022 at 9:00 NeweNewe 1419 bronze badges 3
  • 1 Very same problem. Looks crazy! :0 – Jacopo Pace Commented Apr 26, 2022 at 0:28
  • 1 I am going crazy over this! Did you manage to solve it? – Mitja Kukovec Commented Jun 2, 2022 at 8:15
  • @MitjaKukovec Sadly not; i worked around this by serving the static/ folder via nginx tho – Newe Commented Jun 2, 2022 at 9:02
Add a ment  | 

4 Answers 4

Reset to default 1

This problem can be solved by using a custom server with express to serve the static files. First run "npm run build" and add a server.js file into build path.

// server.js
import { handler } from './handler.js';
import express from 'express';

const app = express();

// add a route that lives separately from the SvelteKit app
app.get('/img/*', express.static('static'));

// let SvelteKit handle everything else, including serving prerendered pages and static assets
app.use(handler);

app.listen(3000, () => {
    console.log('listening on port 3000');
});

Then run "node server.js" instead of "node index.js"

I fixed this problem by using an api endpoint to fetch my files. I also added some performance features. You can check the full article here: my medium article

Actually I found two solutions but both are just workarounds to this very annoying problem.

  • The import way: that's quite tricky to configure it properly (read also this) and, overall, it bees a pain if you need to import dynamic paths (with variables inside the import path) as it was in my case.

  • The CDN way: use the static folder as a CDN by pointing there the webserver with a dedicated (sub)domain. This way you can link assets with success as they are "external" resources (e.g. https://cdn.mysite./file1.png, https://cdn.mysite./file2.jpg).

Bonus: if you choose the CDN workaround, can be a good idea to set handleFetch to bypass the external DNS resolution and keeping traffic internally.

I got to sort it out by serving images in base64 format. So first at all I save the uploaded images out of static directory. Then I have an endpoint that returns the image, but that accept a parameter to apply for base64 format. Then in the html I add in the src of the image the base64 version of it.

My directory tree looks like:

src
├── app.html
├── images
├── lib
└── routes
    └── [imagePath]
        └── +server.js

Then +server.js looks like this:

import { error, json } from '@sveltejs/kit'
import fs from 'fs'

export async function GET({ url, params }) {
  const format = url.searchParams.get('format') ?? ''
  const { imagePath } = params
  const pleteImagePath = `src/images/${imagePath}`
  if (fs.existsSync(pleteImagePath)) {
    const image = fs.readFileSync(pleteImagePath)
    if (format === 'base64') {
      const imageBase64 = fs.readFileSync(pleteImagePath, { encoding: 'base64' })
      return json({ imageBase64 })
    } else {
      return new Response(image)
    }
  } else {
    error(404, {
      message: `Could not find ${params.imagePath}`
    })
  }
}

So now if we GET http://example./imageId.png, for example it will return the image, but if we add format parameter we can get the base64 code: http://example./imageId.png?format=base64

Then now in our .svelte files we can load this image on base64 format and pass it in the way below:

<img src={`data:image/png;base64, ${imageBase64}`} alt="image-alt" />

Where imageBase64 has been retrieved previously.

发布评论

评论列表(0)

  1. 暂无评论