I'm getting this 2 errors when using post request to an API
(Using chrome)
xhr.js:178 POST MY_API_URL net::ERR_HTTP2_PROTOCOL_ERROR
createError.js:16 Uncaught (in promise) Error: Network Error at
createError (createError.js:16) at XMLHttpRequest.handleError
(xhr.js:83)
I'm doing a simple POST request
(React code):
const postData = async()=>{
let res = await Axios.post('/terrenos', {'idTerreno':'0'} );
console.log( res.data );
}
And in the API side I just have this for debugging(PHP Code):
if( $_SERVER["REQUEST_METHOD"] === 'GET'){
main($_GET);
}else if( $_SERVER["REQUEST_METHOD"] === 'POST'){
echo(json_encode($_POST));
}
When I dont send anything in body it works just fine (It returns an empty array)
const postData = async()=>{
let res = await
Axios.post('https://gpgpy.000webhostapp.com/papaProject/API/v2/query.php');
console.log( res.data );
}
And when I use postman for the same request it with and without body it works too.
I ran into the same issue using Axios with React and a PHP web service hosted on 000webhost. It works perfectly fine with Postman as well as the vanilla fetch function. Odd, seems to be a compatibility issue between Axios and 000webhost...
My solution was to use fetch instead of Axios for my API calls, as I didn't see any particular reason to use Axios in my scenario.
Here's a good example on how to use fetch with POST.
Seems like you asked about it 3 months ago, so I hope you found a solution earlier than I could reply. If you managed to utilize Axios with 000webhost, please share your wisdom ๐
Related
I have a probleme while i request SerpStack API using Axios on Chrome browser. I don't know if the probleme comes from my code (I may not be using axios properly) or from Chrome config. To explain each time i request SerpStack API i got that error : {code: 105, type: 'https_access_restricted', info: 'Access Restricted - Your current Subscription Plan does not support HTTPS Encryption.'}. And i don't understand why the API told me that, even if i use the http URL. I tested my code on edge and everything work fine on it.
Here is my code :
<script src="https://unpkg.com/axios#1.1.2/dist/axios.min.js"></script>
<script>
const serpStackAPIKey = "MyAPIKey";
const googleSearchRequestInput = document.querySelector('#googleSearchRequestInput')
const googleSearchRequestBtn = document.querySelector('#googleSearchRequestBtn');
googleSearchRequestBtn.addEventListener('click',serpStackAPIGetRequest)
let googleSearchResultDiv = document.querySelector('#googleSearchResultDiv');
function serpStackAPIGetRequest(){
const request = `http://api.serpstack.com/search?access_key=${serpStackAPIKey}&query=${googleSearchRequestInput.value}`;
axios.get(request)
.then(function(response){
console.log(response);
})
}
</script>
Update
By searching in the network console i find that my initial request have a status code of "307 Internal redirect" and that chrome create a second request with https. How can i prevent Chrome or any other browser to do such a thing ?
I'm having issues sending post requests. Whenever I try and send a post request to localhost:5000/api it gives me this error "POST http://localhost:5000/api 404 (Not Found)" but whenever I do a get request it gives me no errors and works perfectly.
const createPost = async () => {
let res = await axios.post("http://localhost:5000/api", {"id" : 4, "name" : "this was posted by code :)"})
console.log(res)
}
useEffect(() => {
axios.get("http://localhost:5000/api").then(res => {
setBackendData(res.data)
}).catch(err => {
console.log(err)
})
}, [])
If you need anymore of my code please tell me.
Your backend has been written specifically without support for post. If you want, you could read this w3schools article on what different http methods exist. In the modern age, it's all semantic so what api endpoints you choose is up to you (post is generally recommended for security reasons though).
If you want your backend to support post, change your code to use app.post instead of app.get.
I am trying to fetch food by its key. In postman api is working fine but is the forntend it has no response.
backend code
app.get('/foods/:key', (req, res) => {
foodsCollection.find({ key: req.params.key }).toArray((err, documents) => {
res.send(documents[0])
})
})
frontend code
const { key } = useParams()
const [foodById, setFoodById] = useState({})
useEffect(() => {
fetch(`http://localhost:5000/foods/${key}`)
.then((res) => res.json())
.then((data) => {
setFoodById(data)
})
}, [key])
Although you've added some images above, the most important is missing, namely, what are the Browser's Developer Tools stating the problem is. You should see some message in the Console tab, as well as in the Network tab for that particular request, if it is indeed being made. Until anyone sees this, it will be very difficult to help in fixing your problem.
If your not already, I suggest scaffolding any react app with create-react-app (CRA). This will give you a working app to start from. You can ignore CORS related issues in development, if using CRA, by adding "proxy": "http://localhost:5000", to your package.json file, see here for more on this method, but remember, this is only works for local development. You can also start Chrome to ignore Web Security by running it with the --disable-web-security flag e.g. chromium --disable-web-security, but that isn't a great idea really, more a way to quickly determine if you are having CORS problems, as Chrome masks some problems as CORS related, when in fact they aren't.
I'd also suggest changing your fetch code to use await, so instead you'd have:
const response = await fetch(`http://localhost:5000/foods/${key}`);
if (!response.ok) {
console.error(`Error message: ${response.statusText} ${response.status}`);
}
const result = response.json();
console.log(result);
This isn't necessary, but I've always found it way easier to read than the then/catch/finally method.
Reason for error
You need to stringify an object before sending it to the client with the JSON.stringify() method. When we exchange data to/from a web server, it must be a string.
Solution:
Proper way to send response to the client would to wrap the entire API in a try-catch block and explicitly specify the HTTP Status Code along with the stringified data in every response.
Note: Although 500 status code is used for error handling, you should choose one as per the use case.
app.get('/foods/:key', (req, res) => {
try {
/*
rest of the code
*/
foodsCollection.find({ key: req.params.key }).toArray((err, documents) => {
if (err) {
// 500 stands for internal server error
return res.status(500).send(JSON.stringify('Here goes a meaningful error message!'));
}
// 200 stands for success
res.status(200).send(JSON.stringify(documents[0]));
});
/*
rest of the code
*/
} catch (error) {
// 500 stands for internal server error
res.status(500).send(JSON.stringify('Here goes another meaningful error message!'));
}
})
The problem is that you haven't set the CORS headers of response in your backend code. and you are using different ports in your backend and frontend (5000 & 3000) so the Same Origin Policy disallows reading the remote resource, indicating that the request was blocked due to violating the CORS security rules.
you've to set the CORS headers.
you can install the CORS npm package and follow it's instructions to resolve the issue like this:
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
.
.
.
And one other issue that I'm seeing is that you've put the react-router default route before your specified path. so move the <route path="*"> after <route path="/foods/:key">
I am new to node.js and APIs so I am hoping someone can help! I am trying to use node-fetch to get JSON data from the fantasy premier league API. I have successfully done this in the client, but from my node.js server file I keep getting the error:
UnhandledPromiseRejectionWarning: FetchError: invalid json response
body at https://fantasy.premierleague.com/api/entry/3/ reason:
Unexpected end of JSON input
The response itself has a status of 200, but the size is 0 so it is not returning any data. I know it should work, as the JSON is plainly visible when you visit the url and I have got fetch to work in the client-side code.
Here is the code I am using:
const fetch = require('node-fetch');
async function fetchEntry() {
const api_url = 'https://fantasy.premierleague.com/api/entry/3/';
const fetchEntry_response = await fetch(api_url);
const json = await fetchEntry_response.json();
console.log("json: " + JSON.stringify(json));
};
fetchEntry();
Note: On the client-side code I got a CORS error so needed to use a proxy (https://thingproxy.freeboard.io/fetch/https://fantasy.premierleague.com/api/entry/3/) to get it to work. I'm not sure if this is relevant?
Any help would be greatly appreciated!
Joe
Don't ask me why but adding a 'User-Agent' header seems to fix it:
const response = await fetch(URL, {
headers: {
'User-Agent': 'ANYTHING_WILL_WORK_HERE'
}
});
I think the api you're using is the problem. I tried to make it work, but got the same error. Also tried to use axios but it's the same thing.
I tried to fetch data with Postman and it worked perfectly, so.. my guess is that the api you're trying to use does not support all origin, since the API I tried to use works perfectly with your code.
const api_url = "https://randomuser.me/api";
I was facing the same problem when running the test cases. In my test case, there was the API call and I have used the useEffect react hook for updating the state.
useEffect(() => {
getDetailsFromAPI("param")
}, []);
So, While running the test case, I was getting the same error
FetchError: invalid json response body at reason: Unexpected end of JSON input
at ../../node_modules/node-fetch/lib/index.js:272:32
For solving this error I have mock the promise in the test case, which resolved my issue.
import fetch from 'node-fetch';
const mockJsonPromise = Promise.resolve(mydata); // 2
const mockFetchPromise = Promise.resolve({ // 3
json: () => mockJsonPromise,
ok: () => true
});
fetch.mockImplementation(() => mockFetchPromise);
I have an api used for login in my react native app. The api is implemented and working as its supposed to. But the issue is that if the user enters wrong email or password m not receiving the error message in the response in the application. While if i test the api manually in postman it returns the error message required. i tried making a transformer for the error response but m not knowing how to implement it or use it. I'm using fetch to call my apis.
return fetch(fullUrl, requestParameters)
.then((response) => {
if(response.ok) {
return response.headers.get("content-type") === "application/json" ? response.json() : null
} else {
errorrr = ErrorTransformer.backward(response)
console.log("Error: ", errorrr)
}
And below is the tranformer made for the error response
import {createTransformer} from './Transformer';
const ErrorTransform ={
o:[
['message','message'],
['code','code'],
]
}
export default createTransformer(ErrorTransform)
And below is the response returned from postman when wrong info are entered
{
"message": "error",
"code": 1
}
You can check on the basis of the response code. I'll suggest using the Axios library. Axios NPM
After a lot of trials, i figured that the postman response when the user enters wrong email or password is a regular response object, itโs not an error. So its handling should be like a regular response. But what remained as an obstacle is to tell apart when i have a success response with the info returned, or when i have the error object returned. I solved this issue by combining the error transformer with the login transformer, and its handling it perfectly.