I am requesting data from GraphQLHub via XHR:
const query = '{ reddit { subreddit(name: "movies"){ newListings(limit: 2) { title comments { body author { username commentKarma } } } } } }';
const xhr = new XMLHttpRequest();
xhr.open("get", 'https://www.graphqlhub.com/graphql?query=' + encodeURIComponent(query), true);
xhr.responseType = "json";
xhr.onload = () => console.log(xhr.response);
xhr.send();
This works. However I tried converting it into axios like so:
const query = '{ reddit { subreddit(name: "movies"){ newListings(limit: 2) { title comments { body author { username commentKarma } } } } } }';
axios({
url: "https://www.graphqlhub.com/graphql",
method: "get",
data: {
query: encodeURIComponent(query)
}
}).then((result) => {
console.log(result.data);
});
But I am getting this error:
Uncaught (in promise) Error: Request failed with status code 400
Anything wrong with the syntax?
According to the docs:
data is the data to be sent as the request body. Only applicable for request methods 'PUT', 'POST', and 'PATCH'.
Since your method for the request is GET, the data is ignored. You should use params instead. We also don't need to encode our params, since axios already does this for us.
axios({
url: "https://www.graphqlhub.com/graphql",
method: "get",
params: {
query,
}
})
It's probably better to just use POST instead though, since some servers don't allow mutations to be sent as GET requests.
axios({
url: "https://www.graphqlhub.com/graphql",
method: "get",
data: {
query,
}
})
Or, better yet, just use a client like Apollo.
Related
I am not able to receive the resources from an API using different functions in javascript.
It works as follows:
In one tab of the browser I open the application webclient and receive a cookie for that domain:
first_browser_tab
In another tab I open a page of a different domain and using javascript I request the ressource from the API. It runs over a gateway which has the same domain as my endpoint:
second_browser_tab
The cookie is not sent in the request and for this reason I get an authentication error from the endpoint to my request.
I tried to send the request in different ways and it allways fails due to the endpoint authentication.
See the code:
Using fetch
const urlToApiFetch = 'https://app.apple.com/api';
fetch(urlToApiFetch, {
method: "GET",
mode: "cors",
credentials: "include",
headers: {
"Authorization": "Bearer 12345",
"x-api-key": "12345",
}
})
.then((response) => {
console.log(response);
})
.catch ((error) => {
console.log(error)
});
Using XMLHttpRequest
const urlToApiXMLHttpRequest = 'https://app.apple.com/api';
let testUrl = urlToApiXMLHttpRequest;
let xhr = new XMLHttpRequest();
xhr.open("get", testUrl, true);
xhr.setRequestHeader("Authorization", "Bearer 12345");
xhr.setRequestHeader("x-api-key", "12345");
xhr.withCredentials = true;
xhr.onreadystatechange = function(r) {
console.log(r);
}
xhr.send();
Using jQuery
const URL = "https://app.apple.com/api";
$.ajax({
url: URL,
crossDomain: true,
method: "GET",
xhrFields: {
withCredentials: true
},
headers: {
"Authorization": "Bearer 12345",
"x-api-key": "12345",
}
}).done(function(data, status){
console.log(data);
console.log(status);
}).fail(function(data, status){
console.log(data);
console.log(status);
});
Does anyone have an idea on what is wrong? Why does the cookie is not sent?
Thanks a lot
I found the issue...
The response header was missing the parameter:
Access-Control-Allow-Credentials: true
More details here: https://javascript.info/fetch-crossorigin
I have a base request like this:
export const request = (options) => {
const headers = new Headers({
'Content-Type': 'application/json',
});
if (Common.getToken()) {
headers.append('Authorization', 'Bearer ' + Common.getToken())
}
const defaults = {headers: headers};
options = Object.assign({}, defaults, options);
return fetch(options.url, options)
.then(response =>
response.json().then(json => {
if (!response.ok) {
return Promise.reject(json);
}
return json;
})
);
};
and my ajax request:
onCreateNewPost(postDataRequest, photoBody) {
const formData = new FormData();
formData.append('photo', photoBody);
formData.append('postData', JSON.stringify(postDataRequest));
return request({
url: API_BASE_URL + '/posts/new-post',
method: 'POST',
body: formData
});
};
where postDataRequest - json object included post title, description etc...
photoBody - image file.
In the backend I have a controller's method:
#PostMapping(value = "/api/posts/new-post")
#PreAuthorize("hasRole('ADMIN')")
public ResponseEntity createNewPost(#CurrentUser UserPrincipal currentUser,
#RequestBody NewPostDataRequest postRequest,
#RequestParam MultipartFile photo) {
// method body
return ResponseEntity.ok(new ActionCompleteResponse(true));
}
but when I send a request, I get Status Code: 400. What is the problem? I can separately send either json data or multipart data, but I can’t figure out how to transfer them together with one request. I tried to put headers without a Content-Type in the request, as in the code below, so that the request itself indicates it, but in response I get code 415.
onCreateNewPost(postDataRequest, photoBody) {
const formData = new FormData();
formData.append('photo', photoBody);
formData.append('postData', JSON.stringify(postDataRequest));
const headers = new Headers({});
if (Common.getToken()) {
headers.append('Authorization', 'Bearer ' + Common.getToken());
}
return request({
url: API_BASE_URL + '/posts/new-post',
headers: headers,
method: 'POST',
body: formData
});
};
What should I do?
Okay, I found the solution:
1. Clear headers data (except Authorization token)
2. Add to #PostMapping consumes = MediaType.MULTIPART_FORM_DATA_VALUE and add #RequestPart to method parameter
ajax request like:
onCreateNewPost(postDataRequest, photoBody) {
const formData = new FormData();
formData.append('post', new Blob([JSON.stringify(postDataRequest)], {
type: "application/json"
}));
formData.append('photo', photoBody);
const headers = new Headers({});
if (Common.getToken()) {
headers.append('Authorization', 'Bearer ' + Common.getToken())
}
return request({
url: API_BASE_URL + '/posts/new-post',
method: 'POST',
headers: headers,
body: formData
});
};
and spring controller like
#PostMapping(value = "/new-post", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
#PreAuthorize("hasRole('USER')")
public ResponseEntity createNewPost(#CurrentUser UserPrincipal currentUser,
#RequestPart("post") #Valid PostEntity post,
#RequestPart("photo") #Valid MultipartFile photo) throws IOException {
post.setAuthor(currentUser.getUsername());
post.setAuthorId(currentUser.getId());
post.setCommentsCount(0L);
post.setDate(LocalDate.now());
post.setPhoto(photo.getBytes());
postService.save(post);
return ResponseEntity.ok(new ActionCompleteResponse(true));
}
#Sergey Scream solution is correct, I just want to add some information to clarify the problem.
So if you want to send json and a file using FormData you have to wrap your json in a blob including the type like he did:
formData.append('post', new Blob([JSON.stringify(postDataRequest)], {
type: "application/json"
}));
Adding your json like this will not work:
formData.append('post', JSON.stringify(postDataRequest));
You're setting Content-Type to application/json in request but body to form data in onCreateNewPost. If you removed line 3 from request then your current solution should work.
Also you're setting the Authorization header twice in onCreateNewPost and request.
i gonna send a get request, but i need to send with a body,
when i use a postman it works well, but if i use axios, it dosent't works.
i use axios in javascript
and i use postman
var settings = {
"url": "http://127.0.0.1:5000/user/history",
"method": "GET",
"processData": false,
"data": "{"summoner":"몽디로 맞아봐"}"
}
$.ajax(settings).done(function (response) {
console.log(response);
});
axios({
url: 'http://127.0.0.1:5000/user/history',
method: 'get',
data: {
'summoner': '몽디로 맞아봐'
}
});
i expect this code works
ES6:
import axios from 'axios';
let requestHeader, data;
data = {
'summoner': '몽디로 맞아봐'
}
requestHeader = {
'Content-Type':'application/json'
}
axios.get('http://127.0.0.1:5000/user/history', {
params: data,
headers: requestHeader
}).then((response) => {
console.log(response)
})
In HTTP specification, sending GET request with body is ok, you can try it with http module in nodejs.
But, axios' implementation whichs bases on XHR will remove all the body of GET request before sending.
Fetch api do the same thing like axios.
I am trying to access a php script on a server that returns a JSON object. I am trying to do this with pure JS (not jQuery or React).
I have the following JS:
//Define Parameters:
var param1 = document.getElementById("param1");
var param2 = document.getElementById("param2");
//Send data to the server:
function sendData() {
var XHR = new XMLHttpRequest();
//On Success:
XHR.addEventListener("load", function(event) {
alert(event.target.responseText);
});
//On Fail:
XHR.addEventListener("error", function(event) {
alert('Oops! Something went wrong.');
});
//Setup the request:
XHR.open("POST", "https://www.example.com/folder/file.php");
XHR.setRequestHeader('Content-Type', 'application/json');
//Perform the request:
XHR.send(JSON.stringify({
param1: param1,
param2: param2
}));
}
These parameters are inputted from a HTML page by the user. It seams that the request is not sending to POST parameters and the request type is OPTIONS not POST.
EDIT 1:
As suggested in the comments, I have tried a fetch request and the request is working. It does not appear to be passing my POST parameters through. My code is as follows.
//Define Parameters:
var param1 = document.getElementById("param1");
var param2 = document.getElementById("param2");
var formData = new FormData(document.getElementById('form'));
formData.append('param1', param1);
formData.append('param2', param2);
//Send data to the server:
function sendData() {
var url = 'https://www.example.com/folder/file.php';
fetch(url, {
method: 'POST',
body: formData,
headers:{
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
}
}).then(res => res.json())
.then(response => console.log('Success:', JSON.stringify(response)))
.catch(error => console.error('Error:', error));
}
Remove the headers section in your fetch request so that the defaults are used instead.
Have you checked to see that the right type of data is being sent in the fetch request? The wrong type being received in a field can mess with the results you see. What errors are you receiving?
This link may also describe something you're running into on the fetch:
https://stanko.github.io/uploading-files-using-fetch-multipart-form-data/
(This really should be a comment, but I don't have the reputation for that, sorry).
I am trying to convert an ajax request to vanilla JavaScript
$.ajax({
url: 'http://foo.bar/hi',
type: 'post',
data: {args: params},
success: function(data){
},
});
I have tried the following
var xhr = new XMLHttpRequest();
var data = {args: params};
xhr.open("POST", 'http://foo.bar/hi', true);
xhr.send(data);
I am connecting to an external device with a web based interface and not getting any response on the device. It is as if I never sent a request
Theoretically, the original ajax request will perform the action, however, there is a problem with the jQuery portion of my program so I am trying to convert it to vanilla javascript and bypass the jQuery
Using fetch:
function json(response) {
return response.json();
}
function handleErrors(response) {
if(!response.ok) {
throw new Error("Request failed " + response.statusText);
}
return response;
}
fetch("http://url.com/endpoint", {
method: "POST",
body: {
myKey: "my value",
another: "hihihi"
}
}).then(handleErrors).then(json).then(function(data) {
console.log(JSON.stringify(data));
}).catch(function(err){
console.log("err" + err);
})