VueJs 2, NodeJs and reload page - javascript

I have a question with VueJs and the refreshing page. When I refresh my VueJs app with specific URL (for example : /tag/1), an error occurs : "Uncaught SyntaxError: Unexpected token <".
My server is created with NodeJs and I use ExpressJs. My templating engine is EJS.
I have defined a route :
app.get('*', (request, response) => {
response.render('layouts/index')
})
In the documentation for ExpressJs, it's possible to use a plugin "connect-history-api-fallback" to replace ".htaccess" of Apache but this cannot work.
let app = express()
app.use(history({
verbose: true,
index: '/'
}))
What is the issue ?
Thanks,

This is happening because your client app (vue.js) is expecting to receive some valid JSON object, but your server is giving a HTML page.
When attempting to convert some string like <html><head>... into a javascript object, your JSON parser fails and gives that error. To replicate this locally, open your developer console and run the following command:
JSON.parse("<html></html>")
To find out what exactly is going wrong, you need to look into the network tab of developer console and look at the server responses for API requests - you expect JSON but server might be serving index.html
Assuming your server side is all good and handles API requests as expected, then it might be a simple error in your vue component - instead of loading your tag data from /api/tag/1 (which gets a valid JSON string), you might be attempting to load /tag/1 (which will only get your index.html).

Related

Internal server error 403 on deploying react app served via expressjs

I am trying to serve a build react application using expressjs. the react application is built and the index.html is served from my expressjs using:
app.use('/', express.static('reactapp/build'))
The application is simple. it contains a number of cards which when pressing navigates to another page changing the route. Before clicking, it is suppose localhost:3000/lists and after clicking any cards, it routes to localhosts/lists/1, 1 being an id. Now, when i try to refresh the page after pressing the any one of the cards, i get "no handler found for the path"(because it is client side url i suppose and isnot handled by express). the last app.use gets triggered.
app.use((req, res) => {
res.status(404).json({message: `No handler for ${req.url}`, requestHost: req.baseUrl})
})
therefore, what i did was, i sent the index.html inside this middleware part to fix my issue.
app.use((req, res) => {
res.sendFile(path.join(__dirname,"..\\reactapp\\build","index.html"));
})
it solved the problem locally but after deploying i get the "internal server error of status code 403". i am not knowing what the problem is. according to a site: The 403 (Forbidden) status code indicates that the server understood the request but refuses to authorize it...If authentication credentials were provided in the request, the server considers them insufficient to grant access.
Could someone help me out? i am not much familiar with expressjs so i wanted some help on what might be the reason.
res.sendFile(path.join(__dirname,"..\reactapp\build","index.html"));
the way path is setup, doesnot work for linux machines. that might be the reason.

Uncaught syntax error in github deployment

I made a simple website that recommends restaurants based on your city using Zomato API. It works perfectly locally, but when I deployed on a GitHub page it gives me the following
POST https://devangmukherjee.github.io/locations/delhincr 405
(anonymous) # index.js:15
index.js:15 - const res = await fetch(${hostname}/locations/${query}, {
and
index.js:24 Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0
index.js:24 is });
The repo is here - https://github.com/devangmukherjee/random-zomato-restaurant
It is a very small repo only three files.
The website link is here - https://devangmukherjee.github.io/random-zomato-restaurant/
The same code works perfectly locally. What can I do?
When you visit the website locally, you are running your Express backend on localhost too. But, when you visit it on GitHub, your backend isn't executing on GitHub's machines. So, when I write "Mumbai" in the search field, in the line const res = await fetch(`${hostname}/locations/${query}`, { you are actually fetching https://devangmukherjee.github.io/locations/mumbai. Since that GitHub's URL doesn't allow POST HTTP method (because your backend isn't executing there), you are getting a 405 HTTP error. Thus the first error. This response's body is HTML and not JSON. When you do res.json() on line 23 there is a parsing error when it finds the angle bracket of the first HTML tag. And that's the reason for your second error.
To make it work you have to deploy your backend somewhere else, e.g., Vercel or Netlify serverless functions or Heroku (among many other possibilities). And then, update your hostname variable on line 4 accordingly.

Upload JSON File to my server with vue and node js

I'm new to node js and vue development and I want to create a process where I can create and upload a JSON file to my server when the user saves data in a form. This process should be done in the background. Later I want to read and update that file from the server when the user changed something.
So my first idea was to use fs.writeFile() this doesn't work very well and I think this only works for local stuff is that correct?
var fs = require('fs')
export default {
methods:{
send(){
fs.writeFile("/test.json","Hello World!",function(err){
if(err){
throw err;
}
});
}
}
}
Furthermore it looks like fs.writeFile doens't work with vue because it throws this error:
TypeError: fs.writeFile is not a function at VueComponent
So my second idea was to use express js with the app.post('/api/apps',...) and app.get() method. Here I have no idea how to implement that into the vue framework because I have to call the api like mydomain.com/api/apps but this doesn't work too.
So what is the best way to create, read, upload, delte files into a specific folder on my server? And how it works with vue? I tend to express js.
I'm using vue cli :)
Thanks in advance :)
EDIT
Now what I do is:
I created a new folder in my vue project root and named it "backend". In this folder I created a file named index.js and put this code
app.post('/appjson',(req,res) => {
fs.writeFile("/appjson/myJson.json",req.body,function(err){
//handle error
});
});
on the client side I put this code
axios.post('myDomain.com/appjson', {
JSONdata: myJSONdata,
})
My project looks like:
So when I build I get the dist folder and this I can upload on my server and it works fine. But I can't do the call to my backend? Whats wrong do I call the wrong link? Or how can I access my backend? Is the project struture correct or do I need to add the backend to a specific folder?
Vue is client side, your code is trying to write something to the filesystem of the user thats using your website. what you want to do is send this data to your NodeJS server, this requires using a package like Axios to send data to and from the server without refreshing the page. Axios is pretty straight forward to use, what you need will look similar to the function below.
saveJSON (myJSONData) {
const url = myNodeJSURL/savescene
return axios.post(url, {
JSONdata: myJSONdata,
})
Read some tutorials on ExpressJS, It's a pretty painless framework to use. You'll get the data stored in the body of the HTTP request and then you can use fs.writeFile to save data to the local filesystem of your server. Let me know if you need more help.
EDIT:
Your front end needs to be access a domain or IP address associated with your back end in order to communicate with it. Add the snippet below to your ExpressJS application and then when you run the server any requests to localhost:3000 will be handled by your app. You'll also have to update the URL in your Axios call.
app.listen(3000, function () {
console.log('my server is listening on port 3000!')
})
this setup only works for testing purposes because client and server will have to be on the same machine for localhost to mean the same to both. If you want this project to be public then you need to get your own domain for your site and host the ExpressJS application through there. Google compute makes this pretty easy to do, I'd look into that if I were you.

AngularJS: Retrieving Videogular templates stored in $templateCache results 404 Error

I currently develop an AngularJS 1.5.9 Single Page Application on my localhost with NodeJS running backend, where I use
Videogular framework. http://www.videogular.com/
Everything is fine except inserting videogular object on my page. I strictly follow the given example: http://www.videogular.com/examples/simplest-videogular-player/
<videogular vg-theme="controller.config.theme.url">
<vg-media vg-src="controller.config.sources"
vg-tracks="controller.config.tracks"
vg-native-controls="true">
</vg-media>
</videogular>
But it results in AngularJS error:
(sessionId in the request is the auth token not linked to current problem)
I have found the following in videogular.js :
$templateCache.put("vg-templates/vg-media-video", "<video></video>");
$templateCache.put("vg-templates/vg-media-audio", "<audio></audio>");
I have tried to store files locally, and the error disappeared
Actually there are a lot of plugins for Videogular and they all are using $templateCache to store some files in the cache, so it would be very confusing to manually store them locally in my app folder.
How can such files be stored in the cache using $templateCache so they can be extracted properly?
I apreciate your help.
UPDATE
I have tried insert $templateCache.get to directive, where the part is loading with error 404, and it works. But still doesn't work as it supposed to be.
It seems like there is an issue with sessionId that you pass in URL parametrs, do you actually need it?
I guess your interceptor or whatever auth managing module is wrong configured, so you don't check request target URL and id parameters are going to be added for local calls as well as for backend calls.

JSONP and AngularJS

I'm developing software to integrate into a router, like the rest of our stack it's developed using AngularJS, the router manufacturer has an API built into the router which returns JSON(P?).
To be a pain, they've prefixed the JSON response with
while(1);
Then commented out the JSON response, within the (minified) code they've written it is using this, so there is a way to access the data.
Whenever I try (using ngResource) it's just running the while(1); function and causing the browser to crash.
HTTP Response:
while(1); /*[{"username":"admin",
"userlevel":2,
"promptinfo":"",
"enableprompt":false,
"ID":"InternetGatewayDevice.UserInterface.X_Web.UserInfo.1.",
"FirstLogin":1}]*/
Can you use http.get instead ? Meaning is the call made to the same domain that you run it on ? If so, you could parse out the response for anything before and and the [] ?

Categories