Accessing endpoint via SSH tunnel - javascript

I'm running a dev project on my local machine (localhost) which is trying to load data from an endpoint on a server via an SSH tunnel (a React JS SPA).
The SSH tunnel is established fine and the endpoint returns the correct data packet when run in Postman using a simple GET.
But when I try to access the data from my app (fetch and Axios tried) a 200 is returned but unfortunately always with an empty array - rather than a 1k object array.
Below are the 2 simple requests, where 'localhost:8912' is the exposed & mapped port - which works in Postman.
Fetch:
fetch("http://localhost:8912/ENDPOINT/")
.then(res => console.log(res))
.catch(err => {
console.log(err);
return null;
});
Axios:
axios
.get("http://localhost:8912/ENDPOINT/")
.then(data => console.log(data.data))
.catch(err => {
console.log(err);
return null;
});
The result is returned almost immediately within the browser but take a few seconds within Postman due to server-side calculations.
Any suggestions welcomed.

If you don't have a proxy you can combine axios with another npm library — tunnel to establish a HTTPS-over-HTTP tunnel:
import axios, { AxiosInstance } from 'axios';
import * as tunnel from 'tunnel';
const agent = tunnel.httpsOverHttp({
proxy: {
host: 'proxy.mycorp.com',
port: 8000,
},
});
const axiosClient: AxiosInstance = axios.create({
baseURL: 'https://some.api.com:443', // here I specify port 443
httpsAgent: agent,
});
Ref: https://janmolak.com/node-js-axios-behind-corporate-proxies-8b17a6f31f9d

Try replacing localhost with 127.0.0.1
This could be related to the address resolution in the browser vs. Postman.

fetch("http://localhost:8912/ENDPOINT/")
.then(res => return res.json())
.then(res => console.log(res))
.catch(err => {
console.log(err);
return null;
});
fetch returns an object as Promise that contains various information like headers, HTTP status etc. etc.
You have res.json() and various other possibilities. .json() will just return the body as promise with json content.
For more info: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
You can return the data as following:
.arrayBuffer()
.blob()
.json()
.text()
.formData()

Related

How do I make my react app fetch my proxy API?

my api call isn't sending to the proxy url domain. I know that it isn't calling as the console.log in the server isn't going off. Could someone please help me?
//client package.json
"proxy":"http://localhost:3001"
//client app
useEffect(() => {
const apicall = async () => {
try{
const response = await fetch("/")
if (response.status !== 200){
throw new Error()
}
else{
console.log("api call was success")
console.log(response)
}
} catch(error){
console.log(error)
}}
apicall()
}, [])
//server
app.get("*", (req,res)=>{
console.log("apicalled")
res.cookie("refreshToken", 987654321, {
maxAge: 60000,
httpOnly: true
})
res.send("has cookie sent?")
})
Don't have an answer for you, but it looks like you're using create-react-app? I think if you've setup your own server, you don't need to set the proxy in your package.json.
I am running a small react app and trying to access an external api behind my company's proxies. I continue to get the cors error - I've tried setting a proxy in package.json and using setupProxy.js (separately), but haven't had any luck.

NodeJS: #esri/arcgis-rest-request - How to adjust Fetch options?

I am looking to adjust the Fetch request option when making a request with #esri/arcgis-rest-request, but unfortunately I cannot find any documentation related to this.
import fetch from "node-fetch";
import FormData from "isomorphic-form-data";
import arcgisRestRequest from "#esri/arcgis-rest-request";
arcgisRestRequest.setDefaultRequestOptions({ fetch, FormData });
arcgisRestRequest.request("https://www.arcgis.com/sharing/rest/info")
.then(response => console.log(response));
When using the request method I am getting errors regarding the certificate of the NodeJS server:
FetchError: request to https://xxx/server/rest/self?token=xxx=json failed, reason: unable to get local issuer certificate
I would like to pass something like:
const fetchOptions = {
...
agent:new https.Agent({rejectUnauthorized: false}),
...
};
to avoid the certificate error.
How can I accomplish this?
Looking at their code it looks like you should be able to just do
arcgisRestRequest.request(
"https://www.arcgis.com/sharing/rest/info",
{
agent:new https.Agent({rejectUnauthorized: false})
}
)
.then(response => console.log(response));

react fetch response meaning of type

While viewing the response using the fetch api in the react app created with create-react-app, the following output occurred.
I don't get the meaning of type in response. I mean, what type?
Since react dev port and strapi port is different, I set proxy configuration in package.json
"proxy": "http://localhost:1337"
Source code is just a simple fetch request for other port that I'm using with strapi.
useEffect(() => {
(async () => {
const result = await fetch(`${process.env.REACT_APP_API_HOST}/contents`, {
headers: {},
});
console.log(result);
})();
}, []);
What is the meaning of type in this response?
Thanks to #decpk Who commented on my post, finally knew what it means.
https://developer.mozilla.org/en-US/docs/Web/API/Response/type
It literally means the type of response, and
Since I used proxy option for request to cross-origin domain,
the response type meant 'cors' is Response was received from a valid cross-origin request.

Headers not set node.js api push notification

Hello im trying to set up push notifications for my webapp.
I'm getting my subscription like I should.
It saves it to my database correctly.
It sends my notification like it should if there only is ONE user in the db
and i want to send to more than only one user :)
Im using:
Vue.js (framework)
Axios (post)
node.js (api)
mongoDB (database)
Here's my post to API.
await axios({
method: 'post',
url: 'API',
data: {
subscription: JSON.stringify(subscription),
storeId: storeId
},
headers: {
'Content-Type': 'application/json'
}
})
It registreres my post, but then i get an throw error.
that "Can't set headers after they are sent."
I'm using CORS in my app like this:
const cors = require('cors')
const app = express();
app.use(bodyParser.json());
app.use(cors())
app.use(morgan('combined'))
The way I'm handling the post from my website is by finding my subscriptions and then map through and say foreach subscription
webpush
//subscribe routes
app.post('/pushNotification', (req, res) => {
var storeId = req.body.storeId
res.setHeader('Content-Type', 'application/json');
console.log(storeId)
if (req.body.storeId != null) {
console.log('Test1')
//get pushSubscription object
//create payload
const payload = JSON.stringify({ title: 'push test' })
Push.find({
"storeId": storeId
},
'subscription', function(error, response) {
console.log('Test2')
console.log(response)
response.map(item => {
res.status(201).json({});
console.log('Test3')
var subscription = item.subscription
console.log(subscription)
webpush.sendNotification(subscription, payload).catch(err => console.error(err));
})
})
} else {
res.send("failed")
}
})
As i can read around somewhere is it im not setting headers or something right. I have used cors like in tutorials and stuff.
So it's like it is crashing because it iterates wrong.
but i can't see how.
ERROR MESSAGE:
Thanks in advance
you are getting this error because res.status(201).json({}) has already set the headers and sent back the response to the client but webpush.sendNotification also trying to set the headers.You should use only webpush.sendNotification(subscription, payload).catch(err => console.error(err));
res.json([body]) sets the corresponding header and sends the result:
Sends a JSON response. This method sends a response (with the correct content-type) that is the parameter converted to a JSON string using JSON.stringify().
So, first of all you don't need to set header manually.
second, If the response has more than one item, since you can't send multiple result for a request, you shouldn't use res.json in a map.
Moreover, be aware of webpush.sendNotification that it may send a result too.

How to pass Request cookies through node-fetch in isomorphic app?

I'm trying to build isomorphic project using React, Express and isomorphic fetch (based on whatwg-fetch on client and node-fetch on server), from this common boilerplate. I'm using cookies for my access token, and credentials: 'same-origin' on front-end side to send it to GraphQL -- works pretty well.
The problem is that I can't use the same solution for server side -- node-fetch just don't support using of XMLHttpRequest cookies from the box. My fetch request is under few abstract layers from router, so I can't just use cookie value from req.
Here is my server.js code (full version):
server.get('*', async (req, res, next) => {
try {
// some presettings here..
await Router.dispatch({ path: req.path, query: req.query, context }, (state, component) => {
data.body = ReactDOM.renderToString(component);
});
res.send(template(data));
} catch (err) {
next(err);
}
});
and Route's index.js (full version):
export const action = async (state) => {
const response = await fetch('/graphql?query={me{id,email}}', {
credentials: 'same-origin',
});
const { data } = await response.json();
// ...
return <Login title={title} me={data.me} />;
};
How can I pass my token from server.js to my fetch module? Or, maybe there are some better decisions?
First off, I hope you have found an answer by now!
Secondly, cookies are really just headers. If you need to send a cookie to authorize server-side requests, you can always just create the string that you need for the cookie value and send it as a header.
For an example, take a look at how this server-side node-fetch wrapper appends saved cookies to the outbound request: https://github.com/valeriangalliat/fetch-cookie/blob/master/index.js#L17

Categories

Resources