React Native Fetch Request Network Error - react-native

I've seen previous answers on similar queries to this, but i'm still seeing a network error.
Here is my code:
let base64 = require('base-64');
let url = 'https://super_secret.com';
let username = '**supersecret**';
let password = '**supersecret**';
let headers = new Headers();
//headers.append('Content-Type', 'text/json');
headers.set('Authorization', 'Basic ' + base64.encode(username + ":" + password));
let APIcall = function checkOrgCode() {
return fetch(url, {
method: 'GET',
headers: headers
})
.then((response) => response.json())
.then((responseJson) => {
console.log(responseJson);
})
.catch((error) => {
console.error(error);
});
};
If i comment out headers.headers and test a simple un-authorized API like https://jsonplaceholder.typicode.com/posts/1 then everything works fine, so clearly authoriation is failing.
When i test my API and headers in postman everything is fine though. I've also tried directly putting the base64 encoded string directly in the headers rather than using the encode function in my code.

Instead of using new Headers() to create the headers, try just a basic object to make life easy:
return fetch(url, {
method: '**PROPER METHOD HERE**',
headers: {
// 'Content-Type': 'application/json',
'Authorization': `Basic ${base64.encode(username + ":" + password)}`
}
})

erm, so the issue was that the URL i am using isn't in place. I'd been using a hostname file hack which ofcourse works from postman on my PC, but not other mobile devices where i am testing.

Related

Downloading blob (zip) from one endpoint and uploading to different endpoint

I'm trying to download a zip from one endpoint and upload to another from a FE VueJS app, but it ends up corrupted on upload. I can do it with fileSaver but was hoping to skip the intermediate step of dropping it onto a HDD. If I download and POST it with Postman it works fine, so I suspect there's an issue with the responseType or blob type etc, but there's a lot of combinations & permutations. cURL works fine as well, but obviously not applicable here.
This is the code so far, the fetch code/config is from Postman, but how the uploaded file is stored/represented in Postman is opaque. The zipEndpointUp is an endpoint that consumes the file but it returns 'invalid archive'. localhost:8080 is proxied to the actual server to avoid CORs issues.
axios.get("http://localhost:8080/zipDirDown/download.zip, {
headers: {
Authorization: "Basic xxx",
mode: "no-cors",
responseType: 'arraybuffer',
}
}).then(res => {
const blob = new Blob([res.data], {type: "octet/stream"});
let myHeaders = new Headers();
myHeaders.append("Authorization", "Basic xxx");
let formData = new FormData();
formData.append("file", blob, "newZipFile.zip");
formData.append("name", "newZipFile Name");
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: formData,
redirect: 'follow'
};
fetch("http://localhost:8080/zipEndpointUp", requestOptions)
.then(response =>
response.text())
.then(result =>
console.log(result))
.catch(error =>
console.log('error', error));
})
So it turns out I needed to await the res promise (and change the Blob type):
fetch("http://localhost:8080/zipDirDown/download.zip, {
headers: {
Authorization: "Basic xxx",
responseType: 'arraybuffer',
}
}).then(res => {
const asyncBlob = await res.blob();
const blob = new Blob([asyncBlob], {type: "application/zip"});
})

How can I make a basic authorization with angular HttpClient and connect with an api Request?

well i have a problem i tried to connect an api with basic authorization but the server donĀ“t give me access it return a 401(unautorized) my code is:
getApi() {
console.log('here i am in the method for get extensions');
const headers = new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Basic ***********************'
});
const options = {
headers,
withCredentials: true
};
// tslint:disable-next-line:max-line-length
return this.http.post('https://10.100.43.241/json', this.jsonBody, options).map((response: Response) => {
const resToJSON = JSON.stringify(response);
console.log('i am going to return jsonfrom method');
return resToJSON;
});
}
i tried too with postman an it is working as well. i really need to know how can i solved this problem of connection or authorization
note: i am not the administrator about the server
Try this architecture.
Component:
this._appApiService.getApi(this.jsonBody).subscribe(result => {
this.resToJSON = result;
});
Service:
getApi(jsonBody: any) {
// add authorization header with jwt token
let headers = new HttpHeaders({ 'Authorization': 'Bearer ' + this.token });
let options = { headers: headers };
return this.http.post(this.baseUrl + 'https://10.100.43.241/json', this.jsonBody , options);
}

POST fails with ReadableNativeMap cannot be cast to String error

I'm working in React Native, I use PHP for backend and when I use fetch POST request I get so strange error, and I dont know why it happens. I checked the url so it works no problem, also normal fetch() is working without POST but when I try to post it happens. When I try it in local server fetch POST works.. but in server, I get this error :
ERROR : com.facebook.react.bridge.ReadableNativeMap cannot be cast to
java.lang.String
React native codes :
fetch('http://xxx/react_test1', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: inputName,
email: inputEmail,
phone: inputPhone
}),
}).then((response) => response.json())
.then((responseJson) => {
Alert.alert(responseJson);
}).catch((error) => {
alert(error);
});
Alert.alert receives an string, and what you're getting from the fetch response is internally a com.facebook.react.bridge.ReadableNativeMap object (which is what the native implementation for fetch returns).
You can try:
Alert.alert(JSON.stringify(responseJson))
If you were using iOS you'll get a completely different error:
Exception '-[_NSFrozenDictionaryM length]: unrecognized selector ...
Alert.alert only accepts string as input.
Use alert() instead to show the popup.
Example: alert("Response: ", responseJson)
Happy Coding. :)
So with fetch() in javascript you need headers: {} but when switching over to RNFetchBlob you should put the headers directly in the {}
import RNFetchBlob from "rn-fetch-blob";
const aPath = Platform.select({ ios: DocumentDir, android: DownloadDir });
const fPath = aPath + '/' + Math.floor(date.getTime() + date.getSeconds() / 2) + '.xls';
Also if you want to add body in the request then directly add it there.
For example:-
RNFetchBlob.config({
// response data will be saved to this path if it has access right.
path: fPath,
}).fetch('POST', URL, {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: token,
},
JSON.stringify(reqBody)
)
.then(res => {
console.log("response body>>>",res);
})
.catch(function (err) {
console.log(err);
});
that's all enjoy your coding...

React Native fetch API cannot disable caching

I am building android app using react native expo integrated with redux. The API is called using fetch method, but always the cached result is displayed. The server did not receive the request second time. I tried disabling cache with the following code.
export const mymails = (token) => {
return fetch(
API_URL+'?random_number='+ new Date().getTime(), {
method: 'GET',
headers: getHeaders(token)
})
.then(response => response.json());
};
getHeaders = (token) => {
return {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': 'Token token='+token,
'Cache-Control': 'no-cache, no-store, must-revalidate',
'Pragma': 'no-cache',
'Expires': 0
};
}
When I call the API through Postman client I see different result(not cached). I tried adding random number as parameter and setting cache control headers, but still returning cached result. Is there is anything else I could try.
Thanks
There must be a problem with how are you setting up the headers for fetching request.
Try with following,
You can follow the link for the same in the Official Fetch API
const mymails = (token) => {
var myHeaders = new Headers();
myHeaders.set('Accept', 'application/json');
myHeaders.set('Content-Type', 'application/json');
myHeaders.set('Authorization', 'Token token=' + String(token));
myHeaders.set('Cache-Control', 'no-cache');
myHeaders.set('Pragma', 'no-cache');
myHeaders.set('Expires', '0');
return fetch(
API_URL + '?random_number=' + new Date().getTime(), {
method: 'GET',
headers: myHeaders
})
.then(response => response.json());
};

Post 'x-www-form-urlencoded' content with aurelia-fetch-client

The question is simple: how do I post x-www-form-urlencoded content with Aurelia Fetch client?
I need to make the post to a simple ASP.NET Web API server that is using OWIN and Katana for authentication.
An example of what I have already tried:
var loginDTO = new FormData();
loginDTO.append('grant_type', 'password');
loginDTO.append('email', 'test');
loginDTO.append('password', 'test');
return this.http
.fetch(config.router.token, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: loginDTO
});
Obviously, that didn't work as intended. How is the correct way to go about posting the data presented in the example?
The aurelia-fetch-client is built on Fetch specification, and it seems that Fetch always sends FormData as Content-Type: multipart/form-data.
To get around this, you have to convert the parameters to a query string and then set the content-type to x-www-form-urlenconed. You can use jQuery or a custom function to convert the object to a query string. Like this:
//jQuery.param returns something like ?param=1&param2=2 and so on
//params = a plain javascript object that contains the parameters to be sent
this.http.fetch(url, {
body: $.param(params),
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(response => response.json())
.then(response => {
//your magic here
});
Not a good solution, I know, but that's the easiest way I found so far.
You would use FormData like this:
function sendForm() {
var formData = new FormData();
formData.append('email', 'test#test.com');
formData.append('password', '123456');
http.post(url, formData);
}