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 thepublic
folder works for now. The data is shown in theconsole
. 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 myjson
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 mysrc
directory, change my axios path fromhttp://localhost:8080/server/tours.json
tohttp://localhost:8080/src/server/tours.json
it shows404 (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 myroot
and change my path intohttp://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.
- [Vuejs]-How to use vue-moment in vuex
- [Vuejs]-Event_Bus vue variable access to single file component Vue.js – Laravel Mix
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.
- [Vuejs]-Electron ipcRenderer from Vue.js Single File Component
- [Vuejs]-Some css will not load in production mode in nuxt.js
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.