Vue Node.js extract cf-ipcountry cloudflare from request headers - node.js

I'm currently using vue js nuxt for my projects. I'm having trouble parsing request headers to retrieve
cf-ipcountry provided by cloudflare. use case for this is to display different content for different country
My code look something like this under my vue file
async asyncData(context) {
try{
const countryCF = context.req.headers['cf-ipcountry']
}
}
when i try to console.log(countryCF) it won't return it, but if i try to console.log(context.req.headers['cf-ipcountry']) it works fine, it did print out the whole headers, but i just need the cf-ipcountry, did i miss anything? thanks

I used the following:
const country_code = req.headers['cf-ipcountry'] ?? 'unknown';
It worked well for me and did not print the whole headers, just the 2-letter country code.

I realized the reason is due to Nuxt SSR initial load is from server side but subsequent request will be client side thats why its returning error
if (process.server) {
context.app.$cookiz.set('user-country', context.req.headers['cf-ipcountry'])
}
Solve by if process.server and i'm storing it in cookie with this package
https://www.npmjs.com/package/cookie-universal-nuxt

Related

How to access json response data using Axios, node/express backend

I have this project I’m working on and I am using node/express + Axios to retrieve data from a third-party API.
I am attaching an image of the response I am getting from my postman but,
I am having an issue figuring out a way to access and manipulate a specific set of data.
If there are any resources anyone could share that would help I would appreciate it.
as of now I just have:
axios.get('apiUrl')
.then((response) => {
const cardData = response.data;
res.send(cardData);
}
This is the response I get:
for example, I’d like to access the “abilities” property.
Since that property is within the “0" object within the response object, I’m a bit confused as to how to navigate this in the code.
I’ve tried response.data.0 but that doesn’t seem to work.
function retrieve(callback){
//I don't get why you are using request.send here. Are you routing the response elsewhere?
//If you are just consuming a service, use Axios with a callback instead.
//If you're not routing it you won't need Express.
axios.get('apiUrl').then(response => callback(response));
}
function clbk(response){
let obj = JSON.parse(response); //In case you are receiving a stringified JSON
//Do whatever you want with the data
//If you have a number as a key, access it by using []. So, considering your example:
response.data[0]
}
//CALL:
retrieve(clbk);

MERN Stack: Was Not Allowed to Display Insecure Content

useEffect(() => {
async function getRecords() {
const response = await fetch(`http://localhost:5000/record/`);
if (!response.ok) {
const message = `An error occurred: ${response.statusText}`;
window.alert(message);
return;
}
const records = await response.json();
setRecords(records);
}
Yep, Safari does not want to display mixed content...
I tried to connect the client-side React application to server-side ExpressJS & NodeJS application using MongoDB's own tutorial on their website... however I encountered this error on Javascript Console after I deployed the app on Heroku! The form retrieved from the MongoDB database does not properly show up on the website unlike its intended behaviour.
I believe that the problem can be resolved by somehow changing the URL that contains localhost to something other than that; I also tried to set the proxy address on root folder's package.JSON to http://localhost:5000 but it did not make a single change whatsoever.
Please help my fellow StackOverFlow members! Any help would be greatly appreciated!
EDIT: YOU CAN ALSO CHECK OUT THE ACTUAL WEBSITE FOR THE SAKE OF JAVASCRIPT CONSOLE... LINK

Frontend apparently requires Unicode String

I am building the backend for a web application in node.js for which the customer wants to keep the frontend unchanged.
The old backend used SAP and a so called OData Service for communication, that I have no clue about.
I am using Express to handle the requests of the frontend.
Looking at the response of the old backend (Chrome debugger), I can see, that it passed date strings, in the following format:
"\/Date(1636329600000)\/"
I failed to get my response which is send to the frontend to look the same.
I am using (simplified)
let responseHeader = {
'content-type' : 'multipart/mixed; charset=utf-8',
}
res.set(responseHeader)
res.send(response)
where I tried different formats for the response date string in order to get "/Date(1636329600000)/" in the frontend:
response= "\/Date(1636329600000)\/" -> in frontend became "/Date(1636329600000)/"
response= "\\/Date(1636329600000)\\/" -> in frontend became "\\/Date(1636329600000)\\/"
How can I let node know, that is should parse "\/Date(1636329600000)\/" as a unicode string? I really appreciate your help.
Best Jogala

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

Cannot find the file URL using xhr.open('post',url,true) - Status: 404 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.

Resources