PostMan is working but http is giving 404 error in flutter - api

I am using following code for my api. This api is working in postman but showing 404 error code in http flutter.
My flutter code:
RaisedButton(
onPressed: () {
apiCall();
},
child: Text("Press"),
)
Future apiCall() async {
var body =
jsonEncode({"filepath": "patient/reports/1602333458533-Liver.jpg"});
try {
await http
.post('http://3.6.197.52:3100/downloadFile',
headers: {"Accept": "Application/json"}, body: body)
.then((http.Response response) => print(response.statusCode));
} catch (e) {
print(e);
}
}
It is giving error code 404 .
Following is postman result:
Post Man result

You are setting the wrong headers. The Accept header is for determining which result type you expect from the server. From your screenshot (and the data) it seems quite clear, you would expect an image/jpg. On the other hand, you are missing the Content-Type header, which defines what type of data you are sending with your request, in your case application/json. So the server probably can't parse the body correctly.
Assuming, that jsonEncode is just something like JSON.stringify you should do something like the following
Future apiCall() async {
var body =
jsonEncode({"filepath": "patient/reports/1602333458533-Liver.jpg"});
try {
await http
.post('http://3.6.197.52:3100/downloadFile',
headers: {"Content-Type": "application/json"}, body: body)
.then((http.Response response) => print(response.statusCode));
} catch (e) {
print(e);
}
}

Related

React Native Axios Network Error but works fine on postman client

I'm trying to get axios working on a react native project to reach a backend but I am getting the Network Error issue that I just can't seem to debug.
const searchApi = async () => {
try {
let res = await axios.get('https://product.company.com/api/documents/invoices');
console.log(res);
} catch (err) {
console.log(err);
}
}
So if I was to do a get request to the example url provided via Thunder Client or Postman Client, I get the appropriate response of
{
"status": "401 error",
"message": "Token not found."
}
But when done through axios, I seem to get a network error. I'm a little unsure how I can debug this too to get more error logs.
Try with below code:
Replace with Your URL
var config = {
method: 'get',
url: 'https://reqres.in/api/users?page=1',
headers: {
'Content-Type': 'application/json'
}
};
axios(config).then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
It's not a network error but an unauthorized error. You need to pass some authenticated token in the header.

How to add custom content type parser for Nest with Fastify

I need to overwrite the content parser for application/json so my application accepts empty body. Right now it throws:
{
"statusCode": 400,
"code": "FST_ERR_CTP_EMPTY_JSON_BODY",
"error": "Bad Request",
"message": "Body cannot be empty when content-type is set to 'application/json'"
}
I'm trying with:
import { FastifyAdapter, NestFastifyApplication } from '#nestjs/platform-fastify';
import { NestFactory } from '#nestjs/core';
const fastifyAdapter = new FastifyAdapter({
addContentTypeParser: // what should go here
});
const app = await NestFactory.create<NestFastifyApplication>(AppModule, fastifyAdapter);
but I can't figure out what is expected under addContentTypeParser
To allow empty json body, you can add a content body parser like the following. Instead of throwing FST_ERR_CTP_EMPTY_JSON_BODY error, this will set request body to null.
const fastifyAdapter = new FastifyAdapter();
fastifyAdapter.getInstance().addContentTypeParser(
'application/json',
{ bodyLimit: 0 },
(_request, _payload, done) => {
done(null, null);
}
);
You can also set the request body to any value you want using the second argument of the done method.
Setting body to an empty object for example, would be look like this:
const fastifyAdapter = new FastifyAdapter();
fastifyAdapter.getInstance().addContentTypeParser(
'application/json',
{ bodyLimit: 0 },
(_request, _payload, done) => {
done(null, {});
}
);
Also, for those who are getting FST_ERR_CTP_INVALID_MEDIA_TYPE error like me, adding a catch-all content type parser for empty body requests fixes the issue.
const fastifyAdapter = new FastifyAdapter();
fastifyAdapter.getInstance()
.addContentTypeParser(
'*',
{ bodyLimit: 0 },
(_request, _payload, done) => {
done(null, null);
}
);
Tus clients, by default sends a POST request with no content-type and an empty body. Using a catch-all parser fixed my problem.

401 Unauthorized error in Express API post request

I am trying to develop the logic for a POST route handler in Express. I put the following together:
const headers = {
"Authorization":"TS Token asdfghjk-asdf-4567-fghjkl; tid=onfido-token";
"content-type": "application/json"
};
const params = {
"policy_request_id": "onfido_applicantandtoken"
};
app.get("/get_stuff", (req, res) => {
axios
.post("https://third/party/api", {
headers,
params
})
.then(function (response) {
res.json(response.data);
})
.catch(function (error) {
res.json("Error occured!");
});
}
});
I keep getting a 401 Unauthorized for the above. On Postman it works, but with the logic above I get a 401 Unauthorized, specifically in the logs I would get Header 'Authorization' not found or Could not parse authorization header. So I am unclear as to what could be going on with the header.
A lot of posts talk about req.headers, but my req.headers does not have the Authorization token and content-type in there, it has some other token that the API I am trying to connect to I assume needs to reach out to another API.
I have refactored it to look like this:
app.get("/get_stuff", (req, res) => {
axios
.post("https://third/party/api", params, headers)
.then(function (response) {
res.json(response.data);
})
.catch(function (error) {
res.json("Error occured!");
});
}
});
And I am still getting the same exact error.
To be clear the params is not something that gets passed into the URL on Postman, but rather the body of the postman request.
I was able to get it to successfully connect by declaring a global axios default like so:
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
as documented here:
https://www.npmjs.com/package/axios#user-content-config-defaults

How to force axios GET request to send headers?

Even though my code is inside one of my components in Vue, the problem is with Axios, let me explain why. So, I'm trying to get some information, like this:
axios.get('http://localhost:8181/roles/1',
{
headers: {
'Api-Token': 'tokenTOKEN',
'Content-Type': 'application/json'
}
}
)
.then(response => {console.log(response)})
.catch(response => {
console.log(response);
})
So, yes, I'm importing Axios correctly. Yes, I know we should not be sending a Content-Type header in a GET request. However, I already read the RFC 7231 and it doesn't say is impossible, is just not common. So, we want to send a Content-Type header in my request.
So, how do I know it doesn't work? Well, one of my middlewares in my Lumen API goes like this:
<?php
namespace App\Http\Middleware;
use Closure;
class JsonVerifier
{
public function handle($request, Closure $next)
{
if($request->isJson())
{
return $response = $next($request);
}
else
{
return response('Unauthorized.', 401);
}
}
}
I tried to use Postman to send that specific GET request, and it works. I tried to use fetch() like this:
var miInit = { method: 'GET',
headers: {
'Api-Token': 'tokenTOKEN',
'Content-Type': 'application/json'
},
mode: 'cors',
cache: 'default' };
fetch('http://localhost:8181/roles/1',miInit)
.then(function(response) {
console.log(response);
})
and it works! In both cases (with Postman and fetch()) my API returns the desire data.
However, when I try with Axios, I get a 401 response with the "Unauthorized" word, meaning that Axios didn't send the header correctly.
Now, the question. Is there any other way to send headers in an axios GET request? How can I force Axios to send the headers no matter what as it seem to be case with fetch() and Postman?
Axios automatically (as it should) removes the Content-Type header if you're sending a request without a body, as you do with any GET request.
https://github.com/axios/axios/blob/2ee3b482456cd2a09ccbd3a4b0c20f3d0c5a5644/lib/adapters/xhr.js#L112
// Add headers to the request
if ('setRequestHeader' in request) {
utils.forEach(requestHeaders, function setRequestHeader(val, key) {
if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') {
// Remove Content-Type if data is undefined
delete requestHeaders[key];
} else {
// Otherwise add header to the request
request.setRequestHeader(key, val);
}
});
}
You're probably looking for the Accepts header and $request->wantsJson() (or acceptsJson()) instead.

How to change status code of headers of response in serverless framwork?

I want to response personal defined statuscode and some headers.
But I find even I change the status code to 201 the status code is still 200. and my defined header is not in headers.
my handler like:
function createResponse(status, header, body) {
return {
headers: Object.assign(header, {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json;charset=utf-8'
}),
statusCode: status,
body: JSON.stringify(body)
}
}
export const hello = async (event, context, cb) => {
const rep = {
message: 'v1.0',
event: event
};
cb(null, createResponse(201, {}, rep));
return;
};
I use serverless.yml my configuration is:
functions:
first:
handler: handlers/first.hello
events:
- http:
method: ANY
path: first
integration: lambda
How to check to correct code can change status code and response header?
I also find my headers still in response body, How to add my header part in Response headers?
If you think my intergration part have problem, can you give me correct configuration example?
Looks like you have a nested object inside headers.
Reference documentation,
https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
Here is the correct sample code to send the correct response,
exports.handler = function(event, context, callback) {
console.log('Received event:', JSON.stringify(event, null, 2));
var res ={
"statusCode": 200,
"headers": {
"Content-Type": "*/*"
}
};
res.body = "Hello, World !";
callback(null, res);
};
Hope it helps.