Cannot find the file URL using xhr.open('post',url,true) - Status: 404 node js - node.js

Trying to Upload an image by XMLHttpRequest(), have issue understanding what is the correct URL to access file via xhr.open(...).
Following this example for server side code and everything..
var xhr = new XMLHttpRequest();
xhr.open('post','../../../../server/routes/saveImage.js',true);
xhr.onload = function() {
if(this.status ==200) {
resolve(this.response);
} else {
reject (this.statusText);
}
};
The Project directory is something like this
Project
client
app
component
product
addproduct.js <-- xhr.open is called from here
server
routes
saveImage.js <-- File being called
Also regarding paths let me know if there is a more convenient way to check the access path or absolute path to use in url.

I think there is a conceptual problem in many levels.
First, When you are XHRing(ajax) an url that means you are accessing the url from CLIENT SIDE. So, Let's say you have an app and HTTP posting or getting an url. Do you have that file from client side? The answer is obviously NO.
let's say you are hosting the app in:
http://localhost/myapps/app
So, When you access ./someFile.txt, ../someFile.txt and ../../someFile.txt you are actually requesting
./someFile.txt-> http://localhost/myapps/app/someFile.txt
../someFile.txt-> http://localhost/myapps/someFile.txt
../../someFile.txt-> http://localhost/someFile.txt
Now, For your problem. You need to host the Server Side upload code somewhere. The example assumes the Server Side code is hosted in, for example, http://localhost/upload and use xhr.open('post','/upload',true);
You need to understand requireing or importing or fs.readFile a file is accessing the path internally. But when you host the app, any client side code like Ajax(XHR) is accessing the url from outside.

The problem indeed was with setting up a server side route, this was mostly clarified, thanks to the answer from #Arkita and comment from #Kasper. But I went ahead to dig for a solution, which may not be very useful to others as this was a dumb question in the first place, but here it goes..
On client side
xhr.open('post','/saveImage/save',true);
on server side if you are using Express.js or other connect based frameworks
app.post('/saveImage/save',(req,res,next)=> {....})
Also the example I linked above may be outdated, this seems more helpful.

Related

Setting up Swagger Ui in Firebase Functions Server

I've developed an API on Firebase Cloud Functions and I want to include a docs path to it.
I'm using swagger and I could successfully test it locally (localhost:PORT/docs) but when I deploy the function to Firebase it's not working, it redirects me to an authorization page.
I think I figured out why this is:
Let's say the name of my Cloud function is cfunc. Then the base url for it is something like https://region-name-project-name.cloudfunctions.net/cfunc. Based on how I included the swagger documentation:
const swaggerDoc = require('./docs/swagger.config.json')
app.use(
'/docs',
allowCors,
swaggerUi.serve,
swaggerUi.setup(swaggerDoc, {
customCssUrl: '/assets/swagger.css',
customSiteTitle: 'My Function Title',
customfavIcon: '/assets/logo.ico',
swaggerOptions: {
supportedSubmitMethods: [] //to disable the "Try it out" button
}
})
)
the docs should be located at https://region-name-project-name.cloudfunctions.net/cfunc/docs. When I try to access that URL, watching "Network" in my browser DevTools, it attempts a GET at that URL with response 304 and then redirects to https://region-name-project-name.cloudfunctions.net/docs and that's what brings up the Google Authentication page, since there's no Cloud Function named "docs" so Google thinks I'm trying to access something else in Firebase Cloud Functions (the same thing happens if I do something like https://region-name-project-name.cloudfunctions.net/tomato)
But I still don't know how to fix this redirect or why it's happening. I tried adding the Cloud Function URL to the host parameter of the swagger.config.json file, and some modifications to CORS, like allowing more Request Methods, adding json as content type, allowing authentication on headers, but nothing seems to be working.
Hope I was clear enought, if not tell me any other info you need (it's one of my first posts here :B)
Found the SOLUTION
After testing a BUNCH of different things, I found out that the redirection was in fact happening always removing one slice of the path after, for example I changed the docs endpoint to '/something/docs' and when accessing the URL that would be https://region-name-project-name.cloudfunctions.net/cfunc/something/docs it redirected to https://region-name-project-name.cloudfunctions.net/cfunc/docs which did not bring up the Google Authentication thing but now wasn't a valid path for my docs so it returned a 'Cannot GET /cfunc/docs'.
For some reason this redirection DOES NOT happen if you add an extra forward slash ('/') at the end of the documentation URL. So, in the first case, where the endpoint for the documentation is only '/docs', accessing the URL https://region-name-project-name.cloudfunctions.net/cfunc/docs/ does it. I do not know why that is, I'm probably posting an Issue on the swagger repo, but if someone has some extra data on why or how to make it work otherwise it would be awesome to hear.
Hope this helps someone else!
EDIT:
Oh and another thing I forgot, it's apparently better if you setup swagger-ui as if you were using express Router, even if you are not (maybe Firebase loads the Cloud Function with something like a router), so instead of app.use('/docs', swagger-ui.serve, swagger-ui.setup(swagger-file)) do app.use('/docs', swagger-ui.serve) and then app.get('/docs', swagger-ui.setup(swagger-file))

How to display binary images retrieved from API in React.js?

✨ Hello everyone!✨
General Problem:
I have a web app that has about 50 images that shouldn't be able to be accessed before the user logs into the site. This should be a simple answer I suspect, there are plenty of sites that also require this basic protection. Maybe I do not know the right words to google here, but I am having a bit of trouble. Any help is appreciated.
App details:
My web app is built in typescript react, with a node.js/express/mongoDB backend. Fairly typical stuff.
What I have tried:
My best thought so far was to upload them into the public folder on the backend server hosted on heroku. Then I protected the images with authenication middlewear to any url that had "/images/" as a part of it. This works, partially. I am able to see the images when I call the api from postman with the authenication header. But I cannot figure out a way to display that image in my react web app. Here is the basic call I used.
fetch(url,
{
headers: {
Authorization:token,
},
}
);
and then the actual response is just an empty object when I try to copy it
{}
but I also get this when I console log the pure response, some kind of readable stream:
from following related question
I came up with the following: (which is normally wrapped in a asyc function)
const image = await fetch(url,{headers:{ Authorization:token}});
const theBlob = await image.blob();
console.log(URL.createObjectURL(theBlob));
which gives me the link: http://localhost:3000/b299feb8-6ee2-433d-bf05-05bce01516b3 which only displays a blank page.
Any help is very much appreciated! Thanks! 😄
After lots of work trying to understand whats going on, here is my own answer:
const image = await axios(url, { responseType: "blob", headers: {Authorization: token }});
const srcForImage = URL.createObjectURL(image.data)
Why it makes sense now
So I did not understand the innerworkings of what was going on. Please correct me, but the following is my understanding:
So the image was being sent in binary. What I had to do to fix that was to set the reponseType in axios as "blob", which then sent a blob, which I believe means its base 64 encoded instead. Then the function URL.createObjectURL does some magic, and must save it to the browser as part of the page. Then we can just use that as the image url. When you visit it yourself, you must type the 'blob:' part of the url it give you too, otherwise its blank, or stick it in <img src={srcForImage}/> and it works great. I bet it would've worked in the original fetch example in the question, I just never put the url in a tag or included 'blob:' as part of the URL.
That's correct, you send the auth token and the backend uses that to auth the user (check that he exists in the DB, that he has the correct Role and check the jwt too)
The server only responds with the images if the above is true
If your server is responding with an empty object then the problem is the backend not the frontend, console.log what you're sending to the frontend

Call NodeJS function from client-side

I have NodeJS on / path.
On /another.ejs path, I have a little website and I wanna get data from /value path.
I cannot do this call with pure JS and AJAX, because of CORS.
Can I do something like when I click on button, it calls function in NodeJS and return data?
I don't know why CORS is going on in same domain name, but you can try some other ways to get result from routes.
Using proxy to throw result between server and client.
You can use proxy things.
Means creating middle hand (link to another stackoverflow answer)
Also look: PHP: no.php
CORS Module
Also see above comment by codeherk.

Meteor allow-access-control-origin

I'm attempting to use the node-trello package to interact with the Trello API inside a Meteor app. However running through setup and attempting to make an api call in my client-side javascript file, I get this error.
This is my code in my javascript file, following the documentation for the package.
var Trello = require('node-trello');
var t = new Trello(Meteor.settings.public.trelloKey, Meteor.settings.public.trelloToken);
t.get('/1/members/me', function(err, data) {
if(err) throw err;
console.log(data);
});
I'm not exactly sure what the error means or how to fix it so any help would be greatly appreciated.
Google will help you find an answer to your problem, by searching for the error message.
The problem is basically a security one, because you are making http requests from the browser to another site (Trello), and you need to let the browser know that it's ok to allow these requests by setting up some headers. I'll let you research what those are.
A better solution is for you to write a server method to do these things. The server process is not restricted in the requests to other sites that it makes, so you avoid the need to maintain headers, and you also won't hit any firewall issues (because perhaps the user's environment doesn't allow access to 3rd party services like Trello).

nodejs mobile development: how control navigation flow

I am a nodejs newbie and would like to understand the navigation flow when using nodejs to serve mobile applications.
Moible app
index.html
Show all users
Nodejs server snippit
var myData = {
"employees": [
{ "firstName":"John" , "lastName":"Doe" },
{ "firstName":"Anna" , "lastName":"Smith" },
{ "firstName":"Peter" , "lastName":"Jones" }
]
};
res.send(myData);
Question: how do I display this data on another page (users.html)? I've worked with nodejs where I can just render to a specific path and it picks the appropriate Jade file but not sure how to do it since the html / js files are on the phone and not the server.
If you know of an example application I can just look through that code and figure it out.
Thanks for your help.
First of all you need to understand that your node.js is executed on server side, and all it can do - response on requests and do some logic, that stays on the server.
Then there is .html and .js that is sent to your clients (browser), and it is rendered and executed on client-side. This execution and logic is very different, and is focused to provide user interactions and render all sorts of data.
So all you need is be able to 'ask' server for data (request) and then get response, validate it in browser, if it is valid, you can render it using JS.
In order to make your life easier, consider using jQuery.
AJAX - to make requests to server and get response with data.
express.js - web framework for node, helps with routes.
And just generally - go and try things, experiment and it is better to understand whole picture or specific details frist, before you making any decisions.

Resources