[Vuejs]-Keep getting 404 Error for static JSON with axios (vue cli)

4👍

I think the problem is simply that you’ve put the file in the wrong place on your file-system.

Assuming you’re using Vue CLI and you want the URL:

http://localhost:8080/server/tours.json

then you should place the file at the path:

project-root/public/server/tours.json

For reference, index.html will typically be at the path:

project-root/public/index.html

Official documentation:

https://cli.vuejs.org/guide/html-and-static-assets.html#static-assets-handling

There are other ways to achieve a similar effect using custom configuration of the server but dropping static assets into the public folder should work out-of-the-box.

Update:

Based on your comments and the updated question I’m going to try to explain further.

Firstly, completely ignore the axios part here. As you’ve suggested in the question that isn’t the problem. You can replicate exactly the same behaviour by typing these URLs directly into your browser address bar, you’ll get a 404 just the same as you are with axios.

The underlying problem here seems to be that you believe that there’s a direct correspondence between the file structure within your project’s root folder and the ‘routes’, or URL paths. This is not the case. They are two separate things.

Let’s consider for a moment what happens when you make a request to a web server. Not necessarily the Vue development server, any web server.

When you make a request to a web server it is entirely at that server’s discretion to decide what to send back. So a request to http://localhost:8080/server/tours.json involves contacting the server at localhost:8080 and asking it for server/tours.json.

On the face of it that might appear to be asking for the file tours.json from the folder server. However, that is not necessarily the case. It is up to the server to decide what server/tours.json means and what the response should be. Not only does the response not have to the contents of a file but it doesn’t even have to be static. The server could generate a response on-the-fly, maybe based on the result of a database query.

It is really important to understand this. Sending a request of http://localhost:8080/server/tours.json does not necessarily mean ‘give me the file tours.json from the folder server. It is entirely at the server’s discretion to decide what to return.

Now, it is common for a web server to have to handle static assets. The easiest way to store such assets is as files. Rather than configuring individual mappings between URL paths and file-system paths it is generally easier to organise the files in a folder structure that maps conveniently onto the URL paths. Typically the web server would be configured to treat a particular folder as the ‘root’ for static assets and then all the folders/files within that root would be served up using matching URL paths.

In general, the exact mechanism for configuring this would depend on which web server you’re using. Of course we’re specifically interested in the Vue development server, so let’s get back to considering that particular server.

There is a lot of stuff going on behind the scenes with the Vue development server. It is not simply serving up files from the file-system.

The contents of the src folder require a build. They won’t be served up as-is to the browser. The server won’t treat them as static assets. If you try to access http://localhost:8080/src/App.vue you’ll find you get a 404 response. That is to be expected.

Instead the server will go through the contents of the src folder and generate the ‘files’ that it needs. For example it’ll pull apart all the .js and .vue files and use them to create one big app.js containing everything. If you look in the Network tab of your browser’s developer tools you should see the ‘file’ app.js being loaded. But this ‘file’ doesn’t actually exist, it is generated dynamically based on the contents of the files in the src folder.

However, it is common for a Vue project to need some static assets. A default CLI project will have an index.html and favicon.ico. These don’t need to be generated dynamically so it is convenient just to store them as files on the file-system. The Vue server has a special folder, called public, for holding such files. As discussed earlier, any folders/files within that folder will be mapped directly onto equivalent URL paths (what the question calls routes). The folder public is treated as the root folder for these mappings. So a file located on the file-system at project-root/public/server/tours.json will be mapped onto the URL path server/tours.json, in full http://localhost:8080/server/tours.json. The ‘route’ is relative to the public folder, not relative to the project’s root folder.

While that covers the most important details there are a couple of other things I would note for the sake of completeness.

Firstly, strictly speaking the contents of the public folder are not all static. For the file index.html there’s some Webpack magic goes on to inject various things within the page. This is described here but it isn’t something worth dwelling on when it comes to understanding how to serve up a simple .json file.

Secondly, it is also possible to include static assets within the src folder, but only in specific cases. For example, the default Vue CLI project creates a file at src/assets/logo.png. However, there is yet more Webpack magic going on here. Once this has been through the build it will have a URL something like http://localhost:8080/img/logo.82b9c7a5.png. Note that this is significantly different from the original path on the file-system. Webpack will trawl through your .js and .vue files and try to update any relative paths that access src/assets/logo.png to point them at the generated path instead. I’m not going to go into detail about precisely how that works here as I don’t think it is relevant to the original question. Just be aware that there are limits on when it will work, it isn’t actually magic.

There is a somewhat equivalent way of accessing a .json file in the src folder but it doesn’t generate a ‘route’ at all. If you place a .json file somewhere within your src folder then you can import it using import just like you would a .js or .vue file:

import tours from '../server/tours.json'

It is important to appreciate that this is not making a separate AJAX request to the server to load the file. Instead this is telling Webpack to bundle the contents of tours.json into app.js during the build. No ‘route’ will be created for tours.json if you include it this way.

I’ll now go through a couple of the specific remarks in the question to try to clarify where misunderstandings appear to be lurking.

Putting my /server/tours.json into the public folder works for now. The data is shown in the console. This is now where my json file is stored: http://localhost:8080/public/server/tours.json. All fine here.

If you put the file at public/server/tours.json on your file-system then it will be mapped to a URL of http://localhost:8080/server/tours.json. The public will be dropped as it is considered to be the root when it comes to serving up static files.

In the quote above you have claimed that the file is stored at http://localhost:8080/public/server/tours.json. I don’t believe that is correct. As you noted previously in the comments the URL path will not contain the /public part.

You should be able to test URL paths by typing them directly into your browser’s address bar.

If you need to clarify what URL axios is calling then take a look in the Network tab of your browser’s developer tools. That will show you the full URL that it requested.

But when I move my json file into every other folder and changing my route accordingly. It doesn’t matter how I try to adapt my route to the new place of my json file, it keeps showing 404 error.

The Vue server does not create routes for all files. It only creates routes for files inside the public folder. So if you put your file somewhere outside the public folder there won’t be a corresponding route. No amount of tweaking the URL will help, the route does not exist.

For example: If I move /server/tours.json into my src directory, change my axios path from http://localhost:8080/server/tours.json to http://localhost:8080/src/server/tours.json it shows 404 (GET http://localhost:8080/src/server/tours.json 404 (Not Found)). The route to my file should be correct like this.

Afraid not.

Putting it in the src folder won’t have any effect on the available routes. Only putting it in the public folder will cause a route to be created.

You may well have several other files in your src folder. None of these files will be mapped directly onto a route either. If you try to access http://localhost:8080/src/components/Tours.vue you’ll get a 404. Instead these files are bundled up into the Webpack build.

If you have the file src/server/tours.json on your file-system then you can access its contents by using import within your .js and .vue files. However, that is all handled by the build process and has nothing to do with creating routes accessible via URLs. That would be a very different process from loading the file via axios.

It’s obviously not the route which is wrong. Even if I move my json to my root and change my path into http://localhost:8080/tours.json it shows a 404.

If you want to access a file using the URL http://localhost:8080/tours.json then the correct place to put it on your file-system would be:

project-root/public/tours.json

Recall that the root for serving static files is the public folder. It is not the project’s root folder. If you put files outside the public folder then the server will usually just ignore them.

1👍

I have an alternative solution for this kind of problem in .json file

the first thing is to

import projects from '../../static/projects.json' // import this file in your component

declare an empty array in your data

data() {
    return {
        items: []
    }
},

and then create a life-cycle method like created or mounted or etc.

created () {
        let projectData = projects.projects
        return this.items.push(...projectData)
    }

and that’s it works just fine without using fetch or axios.

0👍

I think the main issue here is you have the .json file but you need a server to actually send back a response to your GET http request, in this response you will have the json data.

In summary, axios creates an http request, in this case a GET request, and you need another software to respond to this http protocol, this response will contain json data, headers, etc.

I would recommend looking into something like express framework for this.

👤fYre

Leave a comment