Flutter http POST yields ClientException with no exception message - flutter

I’m trying to POST using package:http/http.dart, but I’m getting a ClientException with no message:
Uriurl = Uri.https(baseURL, path);
return http.post(url, body: request.params, headers: _headers)
How do I find out what the error is? The path var contains a relative, valid path. If I replace it with some random string, I'm not getting the ClientException anymore.

I didn't find any way to receive the error description, but in my case (sometimes error "HttpException: Connection closed before full header was received" instead of blank error) the call was to an https address using Microsoft Internet Information Services as backend, in the SSL settings of the website in IIS i had mistakenly set "Client certificates: Accept" instead of "Client certificates: Ignore", setting "Ignore" solved the problem.

Just wrap it in a try-catch clause and you should see what error is being thrown.
try {
Uri url = Uri.https(baseURL, path);
return http.post(url, body: request.params, headers: _headers)
} catch (ex) {
print(ex); // This is your error
}

Related

CORS error: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response

I'm trying to fetch an image resource that's part of a conversation message.
I've tried both FETCH as well as using AXIOS but I'm getting the same error message.
Here's an example of my FETCH request
const token = `${accountSid}:${authToken}`;
const encodedToken = Buffer.from(token).toString('base64');
let response = await fetch('https://mcs.us1.twilio.com/v1/Services/<SERVICE_SID>/Media/<MEDIA_SID>',
{
method:'GET',
headers: {
'Authorization': `Basic ${encodedToken}`,
}
});
let data = await response.json();
console.log(data);
And here's what Axios looked like
let config = {
method: 'get',
crossdomain: true,
url: 'https://mcs.us1.twilio.com/v1/Services/<SERVICE_SID>/Media/<MEDIA_SID>',
headers: {
'Authorization': `Basic ${encodedToken}`,
},
};
try {
const media = await axios(config);
console.dir(media);
} catch(err) {
console.error(err);
}
Both ways are NOT working.
After looking into it more, I found out that Chrome makes a pre-flight request and as part of that requests the allowed headers from the server.
The response that came back was this
as you can see, in the "Response Headers" I don't see the Access-Control-Allow-Headers which should have been set to Authorization
What am I missing here?
I have made sure that my id/password as well as the URL i'm using are fine. In fact, I've ran this request through POSTMAN on my local machine and that returned the results just fine. The issue is ONLY happening when I do it in my code and run it in the browser.
I figured it out.
I don't have to make an http call to get the URL. It can be retrieved by simply
media.getContentTemporaryUrl();

POST http://127.0.0.1:8000/api/v1/users/ 400 (Bad Request)

I'm following a tutorial verbatim.
The following code throws up a 400 Bad Request error, with the following information:
data: undefined status: undefined statusText: undefined headers:
undefined config: undefined request: undefined
Code
if (!this.errors.length) {
const formData = {
username: this.username,
password: this.password1,
};
console.log(formData);
axios.post("/api/v1/users/", formData);
}
Console.log prints the following, so there's no issue with the data:
{username: 'code#code.com', password: 'code'}
A bit surprised as I've set up CORS and djoser exactly as in the tutorial.
This is the relevant code in urls.py:
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/', include('djoser.urls')),
path('api/v1/', include('djoser.urls.authtoken')),
]
I'm able to go to http://127.0.0.1:8000/api/v1/users/ and view and post via my browser, so the issue must be with axios, but I'm not sure what it is. Any thoughts?
I realised that I'm getting this error when I input (dummy) passwords that are either short (e.g., 4 letters) or look too similar to the username input. For example, "something#something.com" with password "something" will throw up this error, but more sophisticated passwords won't.

When making a request to the Vision API Product Search an error occurs "message": "The request is missing a valid API key."

When I register a service account for the Vision API Product Search there's a json file downloaded into my desktop that has the private key. However, when making a request into this api there's no place to send that JSON. I'll show you the documentation and my code.
I didn't understand also what is the curl request and how to send it using the http post request.
And This is my code:
Future<void> uploadProductSet() async {
var projectId = 'estoOne';
var locationId = 'europe-west1';
var url = 'https://vision.googleapis.com/v1/projects/$projectId/locations/$locationId/productSets';
final responseOne = await http
.post(Uri.parse(url),
body: json.encode({
'displayName': 'Product-Set-One',
}))
.catchError((error) {
throw error;
});
print(resoinseOne.body);
}
You have to send your access token with the Authorization header.
The API seems to use the Bearer authentication method.
So set the following header in your http request: Bearer $authToken
You should get the auth-token from the credentials file you've downloaded
So your code should look something like this: (untested)
await http.post(Uri.parse(url),
headers: { 'Authorization': 'Bearer $authToken' },
body: json.encode({
'displayName': 'Product-Set-One',
})).catchError((error) {
throw error
})

How do I deal with "No 'Access-Control-Allow-Origin' header is present" on a physical phone?

I'm getting what seems to be a common error. "No 'Access-Control-Allow-Origin' header is present" when I try to retrieve the contents of a website on a physical phone (in this case an Android phone).
I've experienced something similar with ionic server where it was getting CORS errors, and resolved it by using proxies in the ionic.config.json file. But I understand I shouldn't have that issue on a physical device.
// searchString = "https://swapi.co/api/films";
searchString = "https://www.example.com";
console.log(searchString);
self.httpClient.get(searchString, { responseType: 'text' }).subscribe(
(data: string) => {
console.log("my data: " + data + " " + searchString);
},
(error: HttpErrorResponse) => {
console.log("my err: " + error.message);
console.log(error);
}
);
When I run it on the phone, if I use https://swapi.co the code returns the web page I expect.
If I use https://www.example.com, I get the following error in the phone's console.
XMLHttpRequest cannot load https://www.example.com/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access. (index):1
my err: Http failure response for (unknown url): 0 Unknown Error 4.js:238
HttpErrorResponse {headers: HttpHeaders, status: 0, statusText: "Unknown Error", url: null, ok: false…}
error: XMLHttpRequestProgressEvent
headers: HttpHeaders
message: "Http failure response for (unknown url): 0 Unknown Error"
name: "HttpErrorResponse"
ok: false
status: 0
statusText: "Unknown Error"
url: null
__proto__: __
The "right" solution seems to be to add a Access-Control-Allow-Origin header to https://www.example.com (which is probably what the owner of http://swapie.co did); however, I don't control that server so I can't.
How can I convince httpClient not to expect these headers?
You can't. CORS is there to prevent what you're trying to do, block cross origin requests for unapproved origins. Best you can try to do is lie about your host but you'll have to throw out your http client and write your own. but IOS or android may have seen you coming and taken measures to prevent such things.

Vue-resource can't get response body when HTTP error 500

I'm trying to handle an HTTP 500 error using vue-resource (1.2.1) this way:
const resource = Vue.resource('items');
resource.get().then(
(response) => {
// Do something with response.body
},
(error) => {
// Do something with error.body,
// even if the HTTP status code is 500.
// But for now it's null...
}
);
There is nothing in error.body, while the actual server's response have something to say... And I really want to get this data to be displayed in a cool way for my app's users to be aware of what's going on (rather than opening dev tools and inspect network's response data).
Is there something I'm missing in Vue http config? Or maybe server-side, does my API needs to respond in a specific way? Or even respond special headers? Or, is it simply a limitation (or a bug) of vue-resource?
EDIT
Here is the content of error, picked from a console.log:
Response {
body: "",
bodyText: "",
headers: Headers…,
ok: false,
status: 0,
statusText: "",
url: "http://my.domain/items",
data: ""
}
And, the content of the actual server response (which I expected to be into error.body, but is not), picked from "network" tab in dev tools :
{
"success": false,
"error": {
"message":"this is the error message",
"details":[],
"stackTrace":[]
}
}