Im currently struggling to convert a fetch get request to an axios get request.
Here is my fetch request:
window.fetch(url, {
headers: {
'Origin': window.location.origin,
},
method: 'GET',
mode: 'cors',
cache: 'no-cache',
credentials: 'same-origin',
})
I am trying to convert it to axios, but am struggling to find corresponding attributes for cache and credentials. Anyone have any idea?
caching:
const config = {
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache'
}
};
const { data } = await axios.get(url, config);
for credentials, check the attribute withCredentials. By default, it is set to false.
Related
I am trying to convert this jQuery call to native Javascript using fetch() as mentioned in MDN (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Supplying_request_options).
$.ajax(
{
method: "GET",
url: CB_ABS_URI + "ajax/get-checkin.php",
dataType: "json",
data: { DwellingUnitID:DwellingUnitID },
})
to
// Example POST method implementation:
async function postData(url = '', data = {}) {
// Default options are marked with *
const response = await fetch(url, {
method: 'GET', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json'
// 'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *client
body: JSON.stringify(data) // body data type must match "Content-Type" header
});
return await response.json(); // parses JSON response into native JavaScript objects
}
postData(CB_ABS_URI + "ajax/get-checkin.php", { DwellingUnitID: DwellingUnitID })
.then((data) => {
console.log(data); // JSON data parsed by `response.json()` call
});
But I can't seem to send GET data in the body. Is adding the query to ajax/get-checkin.php the only way ?
But I can't seem to send GET data in the body
fetch makes a clear distinction between the query string in the URL and the data in the request body (unlike jQuery which switches between them depending on the request method).
Is adding the query to ajax/get-checkin.php the only way ?
Yes, see the documentation:
If you want to work with URL query parameters:
var url = new URL("https://geo.example.org/api"),
params = {lat:35.696233, long:139.570431}
Object.keys(params).forEach(key => url.searchParams.append(key, params[key]))
fetch(url).then(/* … */)
In my application I need to GET some data (for which I provide the native authtoken).
In the same event, however, I also need to POST a second token to be consumed by a few endpoints, for external backend api calls.
How do I POST this second token using my working code below using axios?
Should I extend Authorization bearer or simply POST Spotify Token as string data?
How so?
My code:
getData(event) {
const {token} = this.props.spotifyToken
const options = {
url: `${process.env.REACT_APP_WEB_SERVICE_URL}/endpoint`,
method: 'get',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${window.localStorage.authToken}`
}
};
return axios(options)
.then((res) => {
console.log(res.data.data)
})
.catch((error) => { console.log(error); });
};
For an async await applied to your code would look something like this.
async getData(event) {
const {token} = this.props.spotifyToken
let getRes = await axios.get(`${process.env.URL}/endpoint` {
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${window.localStorage.authToken}`
}
}
let postRes = await axios.post(`${process.env.URL}/endpoint` {
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${window.localStorage.authToken}`
}
}
console.log(getRes.data.data);
console.log(postRes.data.data);
};
In this specific case, where a token is needed to fetch data at backend, I found that passing token at url is more suitable, like so:
#endpoint.route('/endpoint/<select>/<user_id>/<token>', methods=['GET'])
def endpoint(name, user_id, token):
# business logic
and:
const options = {
url: `${process.env.REACT_APP_WEB_SERVICE_URL}/endpoint/${select}/${userId}/${this.props.spotifyToken}`,
method: 'get',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${window.localStorage.authToken}`
}
};
otherwise, backend code would run twice, for POST and GET, which is not desired in my case.
Here is my code:
function uploadImage(payload) {
return fetch('/api/storage/upload/image/', {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data',
Accept: 'application/json',
Authorization: 'Bearer <token>',
},
body: payload,
});
}
function uploadImage2(payload) {
return axios.post('/api/storage/upload/image/', payload, {
headers: {
'Content-Type': 'multipart/form-data',
Accept: 'application/json',
Authorization: 'Bearer <token>',
},
});
}
function test(file, meta_data) {
var formBody = new FormData();
formBody.set('image', file);
formBody.set('meta_data', meta_data);
uploadImage(formBody);
// doesn't work
uploadImage2(formBody);
// works
}
Can someone please explain to me how I'm supposed to send multipart requests with fetch?
The error I get with this code is: 400 bad request, file and meta_data are null.
Do not use this header: 'Content-Type': 'multipart/form-data'.
Remove the header and it should work.
Explanation:
When using fetch with the 'Content-Type': 'multipart/form-data' you also have to set the boundary (the separator between the fields that are being sent in the request).
Without the boundary, the server receiving the request won't know where a field starts and where it ends.
You could set the boundary yourself, but it's better to let the browser do that automatically by removing the 'Content-Type' header altogether.
Here's some more insight: Uploading files using 'fetch' and 'FormData'
Here is what worked for me:
function uploadImage(payload) {
return fetch('/api/storage/upload/image/', {
method: 'POST',
headers: {
Authorization: 'Bearer <token>',
},
body: payload,
});
}
By comparing the cURL requests sent by the browser I discovered that in the axios request has this:
"Content-Type": "multipart/form-data; boundary=---------------------------19679527153991285751414616421",
So I figured that when you manually specify the content type, fetch respects that and doesn't touch anything while still does it's thing the way it wants:-/ so you just shouldn't specify it, fetch will know itself since you are using formData()
I'm quite new to using fetch and I dont know if I'm doing this right since it works fairly well with POST. If I use the normal fetch method, and not the function I made, the server responds with the data. But if I use this, the data becomes undefined. Any ideas on how I can fix this?
network_requests.js
export const getData = (url, data) => {
return fetch(url, {
body: JSON.stringify(data), // must match 'Content-Type' header
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'include', // include, same-origin, *omit
headers: {
'user-agent': 'Mozilla/4.0 MDN Example',
'content-type': 'application/json',
'Authorization': 'Token '+ localStorage.token
},
method: 'GET', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, cors, *same-origin
redirect: 'follow', // manual, *follow, error
referrer: 'no-referrer', // *client, no-referrer
})
.then(response => response.json()); // parses response to JSON
};
sample usage: (doesnt work)
fetchDrivers() {
return getData('/members/drivers').then(data => {
if (!data["error"]) {
//for each entry in drivers data, append data as a dictionary in tableData
//ant tables accept values {"key": value, "column_name" : "value" } format
//I cant just pass the raw array since its a collection of objects
const tableData = [];
//append drivers with their ids as key
data["drivers"].forEach(item => tableData.push({
"key": item.id,
"name": item.name
}));
this.setState({drivers: tableData});
} else {
console.log(data["error"]);
}
});
}
I am trying to make a post request using FETCH in react-native. I am getting a validation error. What am I missing here?
_fetchYelp(){
let data = {
method: 'POST',
body: JSON.stringify({
'client_id': 'id',
'client_secret': 'secret',
'grant_type': 'client_credentials'
}),
headers: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded'
}
}
return fetch('https://api.yelp.com/oauth2/token', data)
.then(response => response.json());
}
Error
status 400
timeout 0
response {"error":{"code":"VALIDATION_ERROR",
"description":"client_id or client_secret parameters not found. Make sure to provide client_id and client_secret in the body with the application/x-www-form-urlencoded content-type"}}
response_url https://api.yelp.com/oauth2/token
Thank you.
getAccessToken() {
let formData = new FormData();
formData.append('grant_type', 'client_credentials')
formData.append('client_id', 'yourID')
formData.append('client_secret', 'yourSecret')
let headers = new Headers();
return fetch('https://yourBaseUrl/oauth2/token/', {
method: 'POST',
headers: headers,
body: formData,
})
.then((response) => response.json())
}