I have to make a post call to upload a image. Getting an error due to the boundary values in the header. (Regex not matched)
var requestUrl = API_URL;
// INITIALIZE MULTIPART REQUEST
http.MultipartRequest request;
// PREPARE HEADER VALUES
request = new http.MultipartRequest("POST", Uri.parse(requestUrl));
Map<String, String> headers = {
'Content-Type': 'multipart/form-data',
'Accept': 'multipart/form-data',
'Authorization': 'Bearer '+accessToken,};
request.headers.addAll(headers);
// DECLARE FILE NAME WEB
String imageType = "image." + this.xfile!.mimeType.toString().split('/').last;
// ADD TO REQUEST
request.files.add(http.MultipartFile.fromBytes('image', await this.xfile!.readAsBytes(), filename:imageType ));
// SEND REQUEST
http.StreamedResponse responseAttachmentSTR = await request.send();
I deployed the codes to the server. Apparently this causes a 403 Forbidden error, when I try to upload an image.
Through debugging, it was because of the regex in the Header (Boundary):
boundary=dart-http-boundary-poYEiL0Ungmxkla.2lkZeC6Mub.-Fupw5T_MmJpxColFVjXf-qr
What can I do about this?
Related
I am doing a post request in flutter to a google cloud function:
final uri = Uri.parse(
'https://example.cloudfunctions.net/send_to_queue');
final bearer = 'Bearer ${await user.getIdToken()}';
final response = await http.post(uri, body: json.encode(data),
headers: {HttpHeaders.authorizationHeader: bearer, 'Content-Type': 'application/json'});
In the Google Cloud I print(request.headers) I see a bunch of headers but no Authorization or Content-Type headers.
What should I do?
P.S. Same issue in here Flutter calling firebase cloud function admin.auth.updateUser but I don't want to use a callable function
The browser was sending an OPTIONS request (preflight) before the POST.
I needed to change the Google Cloud Function to handle this:
def main(request):
# Set CORS headers for the preflight request
if request.method == 'OPTIONS':
# Allows GET requests from any origin with the Content-Type
# header and caches preflight response for an 3600s
headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
'Access-Control-Max-Age': '3600'
}
return ('', 204, headers)
# Get token from request
token = request.headers.get('Authorization').split('Bearer ')[1]
etc..
I'm trying to upload a binary file to Dropbox using https://github.com/dart-lang/http. Following https://dropbox.github.io/dropbox-api-v2-explorer/#files_upload, my code is:
import 'package:http/http.dart' as http;
Map<String,String> headers = {
'Authorization': 'Bearer MY_TOKEN',
'Content-type': 'application/octet-stream',
'Dropbox-API-Arg': '{"path": "/file", "mode": "overwrite"}',
};
final resp = await http.post(
Uri.parse("https://content.dropboxapi.com/2/files/upload"),
body: "--data-binary #\'/my/binary/file\'",
headers: headers);
file gets uploaded, but unfortunately this only contains the text --data-binary #'/my/binary/file' (i.e. not the actual file).
Am I missing something/doing something incorrectly?
Sending binary data directly as the body worked:
import 'package:http/http.dart' as http;
final file = File('/my/binary/file');
Uint8List data = await file.readAsBytes();
Map<String,String> headers = {
'Authorization': 'Bearer MY_TOKEN',
'Content-type': 'application/octet-stream',
'Dropbox-API-Arg': '{"path": "/file", "mode": "overwrite"}',
};
final resp = await http.post(
Uri.parse("https://content.dropboxapi.com/2/files/upload"),
body: data,
headers: headers);
Since you pass
body: "--data-binary #\'/my/binary/file\'",
as the body of your POST request, exactly this is the data to get send to the server. The body is raw data, that just gets passed along to the server and in no way interpreted by dart.
Have a look at Dart's MultipartRequest. Or for general information:SO on multipart requests.
I can't seem to make a proper http request with my code. Whenever I run the following code,
var url = Uri.https('datamall2.mytransport.sg', '/ltaodataservice/BusArrivalv2?BusStopCode=', {'BusStopCode': busStopCode});
final response = await http.get(
url,
headers: <String, String>{
'Content-Type': 'application/json',
'AccountKey': accountKey,
},
);
I get the following error
I/flutter (24816): SocketException: OS Error: Connection refused, errno = 111, address = datamall2.mytransport.sg
This is the http request I'm trying to make
http://datamall2.mytransport.sg/ltaodataservice/BusArrivalv2?BusStopCode=busStopCode (busStopCode is a 5 digit number)
The wrong protocol is being used.
You've requested httpS.
The server is only responding to http.
You could try something simpler:
String url = 'http://datamall2.mytransport.sg/ltaodataservice/BusArrivalv2?$busStopCode';
final response = await http.get(
url,
headers: <String, String>{
'Content-Type': 'application/json',
'AccountKey': accountKey,
},
);
You should change your url variable to:
var url = Uri.http('datamall2.mytransport.sg', '/ltaodataservice/BusArrivalv2', {'BusStopCode': busStopCode});
I am using http client for flutter network call.
My request working on postman getting response properly,
But while trying with http.post it returns error code 307-Temporary Redirect,
Method Body:
static Future<http.Response> httpPost(
Map postParam, String serviceURL) async {
Map tempParam = {"id": "username", "pwd": "password"};
var param = json.encode(tempParam);
serviceURL = "http:xxxx/Login/Login";
// temp check
Map<String, String> headers = {
'Content-Type': 'application/json',
'cache-control': 'no-cache',
};
await http.post(serviceURL, headers: headers, body: param).then((response) {
return response;
});
}
Also, the same code returns a proper response to other requests and URLs.
First I trying with chopper client but had same issue.
I am unable to detect that issue from my end of from server-side.
Any help/hint will be helpful
Try to put a slash / at the end of the serviceUrl. So, serviceUrl is serviceURL = "http:xxxx/Login/Login/" instead of serviceURL = "http:xxxx/Login/Login".
This works for me.
You need to find a way to follow redirect.
Maybe postman is doing that.
Read this >>
https://api.flutter.dev/flutter/dart-io/HttpClientRequest/followRedirects.html
Can you try with using get instead of post? At least to try and see what happend
In the documentation said:
Automatic redirect will only happen for "GET" and "HEAD" requests
only for the status codes
HttpStatus.movedPermanently (301),
HttpStatus.found (302),
HttpStatus.movedTemporarily (302, alias for HttpStatus.found),
HttpStatus.seeOther (303),
HttpStatus.temporaryRedirect (307)
keeping https instead of http in the URL it is helping me.
#Abel's answer above is correct but I had to switch from using:
Uri url = Uri.https(defaultUri, path);
to
Uri url = Uri.parse('https://todo-fastapi-flutter.herokuapp.com/plan/');
to get that last / after plan.
The first way kept dropping it so I was getting 307 errors.
flutter.dev shows a full example:
Future<http.Response> createAlbum(String title) {
return http.post(
Uri.parse('https://jsonplaceholder.typicode.com/albums'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, String>{
'title': title,
}),
);
}
here: https://flutter.dev/docs/cookbook/networking/send-data#2-sending-data-to-server
For Dio Http Client, use Dio Option follow redirect as True
getDioOption(){
return BaseOptions(connectTimeout: 30, receiveTimeout: 30,
followRedirects: true);
}
I am making a flutter application, and i have written a server in django. When i send a token to my server for authentication then my server sends me an error of undefined token. Without token all requests works fine, but when i add a token then it gives me an error
{detail: Authentication credentials were not provided.}
But When i add token in modheader, my server works fine
Authorization: Token bff0e7675d6d80bd692f1be811da63e4182e4a5f
This is my flutter code
const url = 'MY_API_URL';
var authorization = 'Token bff0e7675d6d80bd692f1be811da63e4182e4a5f';
final response = await http.get(
url,
headers: {
'Content-Type': 'application/json',
'Authorization': authorization,
}
);
final responseData = json.decode(response.body);
print('responseData');
print(responseData);
try this:
Map<String, String> headers = {
HttpHeaders.contentTypeHeader: 'application/json',
HttpHeaders.acceptHeader: 'application/json',
HttpHeaders.authorizationHeader: 'Token bff0e7675d6d80bd692f1be811da63e4182e4a5f'
};
& use them in request
final response = await http.get(
url,
headers: headers,
);
As I don't know to work on your API so I can't tell you the exact answer.
Check that, Is your backend taking authorization by header or body or
I'll suggest you first make authorization by tools like postman then
if that succeeds then try to implement that in your app.