React native ios http featch method fail - javascript

How to access the react native ios http featch
fetch('http://10.0.2.2:53396/index.cfm/?fwreinit=1', {
method: 'POST',
headers: { 'Accept': 'application/json','Content-Type': 'application/json',},
body: JSON.stringify({ public_key: "Arunkumar" ,private_key: "cfarun",})
}).then((response) => response.json())
.then((responseData) => {
console.log(responseData);
})

You can fix this issue by 1. using https link for your endpoints 2. Update info.plist file and add 'App Transport Security Settings' -> 'Allow Arbitrary Loads' and set its value to 'YES'.
See attached

Answered here
By default, iOS will block any request that's not encrypted using SSL. If you need to fetch from a cleartext URL (one that begins with http) you will first need to add an App Transport Security exception.

Related

not able to fetch remote json link from local html file in chrome

I want to fetch a json from link [https://www.nseindia.com/api/equity-stockIndices?index=NIFTY%2050]
When I open in browser it dumps the json on screen; good as expected but when I try to fetch this link from javascript it gives me cors error.
Please help me by giving a working solution. I am not a pro programmer.
Preferably I don't want a server in middle. Server solution is considered as last option if not possible without it. Currently I am using nodejs server in middle.
Error I get when I run code
I tried with this code in javascript
fetch('https://www.nseindia.com/api/equity-stockIndices?index=NIFTY%2050', {
method: 'GET',
headers: {
'Accept': 'application/json',
},
})
.then(response => response.json())
.then(response => console.log(JSON.stringify(response)))
This is due to cors header missing. CORS stands for cross orging resource sharing. This header tells the server/backend to permit any origins (like www.google.com) except its own from which a browser should permit loading resources.
Here is the fix to your code
fetch('https://www.nseindia.com/api/equity-stockIndices?index=NIFTY%2050', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Access-Control-Allow-Origin':'*',
},
})
.then(response => response.json())
.then(response => console.log(JSON.stringify(response)))

Downloading large files with axios

I am currently downloading large files to my client code using the axios lib. Files are around 600MB. But during the download process the page crashes, like it runs out of memory or similar.
I need to hold the file in the memmory because the content is encrypted and I need to decrypt it before passing it to the user.
I use the REST GET Http request like this:
axios.get(url, {
headers: {
"Authorization": authHeader().Authorization,
"Accept" : "application/octet-stream, application/json, text/plain, */*"
}, responseType: 'arraybuffer'
})
.then(function(response) {
console.log(response);
Are there any common workaround around the problem. So far I wasn't able to find any.
Open the url in the new tab on the client side using
window.open(url)
Let the browser handle the document automatically,
If you want to decrypt the data, please try to decrypt on server side since you'll be giving out decryption key on the client side, which can have security issues.
Do you actually need to do it with axios? There is the Fetch API, which can serve the purpose. Here's how I do it for files in the same size range as yours (media files and ZIPs of up to 1 GB):
fetch(url, {
mode: 'no-cors', // to allow any accessible resource
method: 'GET',
})
.then((response) => {
console.debug('LOAD_FROM_URL::response', response);
//NOTE: response URL is possibly redirected
See https://github.com/suterma/replayer-pwa/blob/main/src/store/actions.ts for more context.
It's working flawless so far for me.
Can you please give a try by setting maxContentLength and maxBodyLength to Infinity in the axios call.
axios.get(url, {
headers: {
"Authorization": authHeader().Authorization,
"Accept" : "application/octet-stream, application/json, text/plain, */*"
},
responseType: 'arraybuffer',
maxContentLength: Infinity,
maxBodyLength: Infinity
})
.then(function(response) {
console.log(response);
}
You can also have a look into this axios issue forum for the same.
HTTP Protocol: Range Parameter
Use the 'Range' header for getting big files part by part.
Example Curl HTTP Request : https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests
curl http://i.imgur.com/z4d4kWk.jpg -i -H "Range: bytes=0-1023"
Example JS
axios.get(url, {
headers: {
"Authorization": authHeader().Authorization,
"Accept" : "application/octet-stream, application/json, text/plain, */*",
//--------------------------|
"Range" : "bytes=0-1023" // <------ ADD HERE
//--------------------------|
},
responseType: 'arraybuffer'
}).then(function(response) {
console.log(response);
}
You need to revisit the design of your frontend. Either its ReactJs or Angular or plain JS, just Offload such large downloads as well as other long running scritps to a concept of JavaScript Web Workers. This is latest way to offloading javascript tasks to the background so the page responsiveness remains intact.
Otherwise JavaScript is single threaded so there is no way to bypass the issue. WebWorkers are only thing to make exceptions here
It is as of today now supported on all latest browsers.
More on this: link

How do I fetch cookie data with React?

I have a MERN + Passport.js application that is using fetch to make a call to my express API in order to retrieve data stored in a cookie. I have my React frontend routed to localhost:3000, and my backend routed to localhost:3001. My cookies are not being saved, and thus my session is not persisting within my browser. It is not an issue with the express-sessions or passport middleware, as when I use POSTMAN to execute the necessary calls to my API, the cookie is stored and the session persists.
It is only when I attempt to pass this information through/to my front end that things go wrong. I have been stumped for a while and can't seem to find an answer anywhere.
This is the line that I am using to save the cookie:
handleLogin(event) {
event.preventDefault();
fetch("http://localhost:3001/users/login", {
// credentials: 'include',
credentials: 'same-origin',
method: "post",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: this.state.username,
password: this.state.password
})
})
// .then( (response) => response.json())
.then( (response )=> {
if(response.message){
alert(response.message);
}
})
Which correctly calls my API, which logs the current session, user data, and cookie.
Upon refreshing and making another request, I lose the cookie (it was never properly stored in the first place I think), and all session data.
This is the get request that I make whenever I navigate to a new page:
componentDidMount(){
var current_user = "";
fetch("http://localhost:3001/users/", {
// credentials: 'include',
credentials: 'same-origin',
method: "get",
headers: {
'Accept':'application/json',
'Content-Type': 'application/json'
}
})
// .then( (response)=> response.json())
.then( (response)=> {
if(response.user){
current_user = response.user;
this.setState({
user: current_user
}), ()=> console.log(response);
}
})
}
In response, I get an undefined user and no other response, and the cookie is never stored in my browser. But again, if I do this in POSTMAN, strictly doing the POST request followed by that GET request, the proper user data is returned and the cookie is shown in POSTMAN as well.
Any idea as to why fetch is not passing the cookie information back to my front end? I have tried both credentials: 'include' and credentials: same-origin.
Thank you!
It seems like the problem, or at least part of it, is your use of same-origin. From Mozilla docs (italics my own):
omit: Never send cookies.
same-origin: Send user credentials (cookies, basic http auth, etc..) if the URL is on the same origin as the calling script. This is the default value.
include: Always send user credentials (cookies, basic http auth, etc..), even for cross-origin calls.
The definition of "same origin" does not include different ports.
If you change same-origin to include, fetch should start managing your cookies correctly.
If not - do you know for sure that the cookie is "never stored in the browser"? With Chrome, you can check chrome://settings/siteData.

Client side certificate javascript request

We're developing a react app with a python flask backend. Normally it all works fine, but when placing it behind a server with client side certificate requirement it almost works. It works fine in Chrome, not in Firefox.
The certificate is sent when entering the URL in the browser, it's not sent when making request from react.
The main request finishes fine, the page is displayed.
When loading the page makes a request to the backend, /backend/version.
That request fails, with nginx saying
<html>
<head><title>400 No required SSL certificate was sent</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<center>No required SSL certificate was sent</center>
<hr><center>nginx/1.10.3</center>
</body>
</html>
When I open devtools and paste the same url, it works fine. The client side certificate is sent by the browser.
How we make the request:
const fetchVersion = () => (dispatch, getState) => {
return dispatch({
[CALL_API]: {
endpoint: `${API_ROOT}/version`,
method: 'GET',
headers: {
"Authorization": authHeader(),
},
types: [FETCH_VERSION_REQUEST,
{
type: FETCH_VERSION_SUCCESS,
payload: (action, state, res) => {
const contentType = res.headers.get('Content-Type');
if (contentType && ~contentType.indexOf('json')) {
return res.json().then(json => json.response);
}
},
},
{
type: FETCH_VERSION_FAILURE,
meta: (action, state, res) => checkIfInvalidToken(action, state, res, dispatch),
}
],
},
});
};
What's missing? Why doesn't Firefox attach the certificate to the request like Chrome does?
You might try to see if the problem is resolved by explicitly specify [CALL_API].credentials value to include
According to the documentation
the default value is omit but firefox need include always send cookies, even for cross-origin calls.
Regarding the example in your question, the code could become something like:
[CALL_API]: {
endpoint: `${API_ROOT}/version`,
credentials: 'include',
method: 'GET',
headers: {
"Authorization": authHeader(),
},
...and so on
In a laboratory with purely experimental purpose I think I have reproduced a similar behavior you reported both with Chrome and Firefox and in this lab the credentials: 'include' solves the problem: video available here.

Access-Control-Allow-Origin Error Workaround - No Access to Server

I'm getting the following error using AJAX to call an API on UPS
XMLHttpRequest cannot load https://wwwcie.ups.com/rest/Ship. Response to
preflight request doesn't pass access control check: No 'Access-Control-Allow-
Origin' header is present on the requested resource. Origin
'http://localhost:63786' is therefore not allowed access.
AJAX Call:
$.ajax({
url: "https://wwwcie.ups.com/rest/Ship",
type: "POST",
dataType: 'json',
crossDomain: true,
contentType: 'application/json',
data: JSON.stringify(message),
success: function (result) {
//code to execute on success
}
error: function (result) {
//code to execute on error
}
})
I have no control over the API server so I cannot modify the headers being sent back. I've tried JSONP, changing the headers I send, and a number of other solutions to no avail. I've read that making a server-side proxy could be a possible fit but I'm not sure how I would go about this. Any advice/code samples on possible solutions would be greatly appreciated. Thanks in advance.
What is to stop a malicious website from sending requests to your bank's web app and transferring all of your money? To prevent these types of shenanigans, if you're using a web browser, the server must explicitly state which remote origins are allowed to access a certain resource, if any.
If you need a key to access it, then CORS probably isn't enabled. You can always double check by looking at the response headers. See this:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
So as others have already mentioned, you can get around this by making the request from your own server (where the headers don't identify it as a browser and subject to CORS limitations), and proxy it to your client side app.
Assuming you're using Node/Express, something like this should work:
const express = require('express');
const app = express();
const myHeaders = new Headers();
const myInit = { method: 'GET',
headers: myHeaders,
mode: 'cors',
cache: 'default' };
app.get('/ups/stuff/stuff', (req, res) => {
fetch('/ups/api/stuff', myInit)
.then(response => response.json())
.then(json => res.json(json);
});
app.listen(3000);
The native fetch API is neat because you can use it on both client and server, and it supports promises like jQuery.
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

Categories