I've similar question like Urlencoding in Dart. I can encode Map, by HttpRequest.postFormData. But JQuery post method can encode Map<String, dynamic>. JQuery example:
$.post("controller",
{actualTime: 1357089552, events: [{priceInsert: 1.32128, priceExecution: 1.32128}]},
function(data) {/*handle*/});
Firebug HttpRequest post view:
actualTime 1357089552
events[0][priceExecution] 1.32128
events[0][priceInsert] 1.32128
Payload source is:
actualTime=1357089552&events%5B0%5D%5BpriceInsert%5D=1.32128&events%5B0%5D%5BpriceExecution%5D=1.32128
Dart can't do it easily. Someone has this problem solved?
PHP with nette requires to set some header:
X-Requested-With:XMLHttpRequest
Content-Type:application/x-www-form-urlencoded; charset=UTF-8
I've some dirty quick fix. Not complete, not tested, working for me:
Map<String, dynamic> data = {"actualTime": 1357089552, "events": [{"priceInsert": 1.32128, "priceExecution": 1.32128}]};
StringBuffer urlData = new StringBuffer("");
bool first = true;
void urlEncode(dynamic sub, String path){
if(sub is List){
for(int i = 0;i<sub.length;i++){
urlEncode(sub[i], "$path%5B$i%5D");
}
}else if(sub is Map){
sub.forEach((k,v){
if(path == ""){
urlEncode(v, "${Uri.encodeQueryComponent(k)}");
}else{
urlEncode(v, "$path%5B${Uri.encodeQueryComponent(k)}%5D");
}
});
}else{
if(!first){
urlData.write("&");
}
first = false;
urlData.write("$path=${Uri.encodeQueryComponent(sub.toString())}");
}
}
urlEncode(data, "");
HttpRequest xhr = new HttpRequest();
xhr
..open('POST', url)
..onLoadEnd.listen((ProgressEvent event){/*handle success*/}, onError: (){/*handle error*/})
..setRequestHeader("X-Requested-With", "XMLHttpRequest")
..setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
..send(urlData.toString());
Related
hello i wonder to upload images in flutter
i try to use http.MultipartRequest
like this
request.fields["name"] = "$RegisterName";
request.fields["description"] = "$RegisterDescription";
request.fields["caution"] = "$RegisterCaution";
request.fields["price"] = "$RegisterPrice";
request.fields["price_prop"] = "$RegisterPriceProp";
request.fields["user.id"] = "1";
request.fields["lend"] = "$RegisterCategory";
request.fields["category"] = "Digital";
request.fields["place_option"] = "true";
var multipartFile = http.MultipartFile.fromBytes(
'file',
(await rootBundle.load('assets/images/main_1.jpg')).buffer.asUint8List(),
filename: 'test01.jpg',
contentType: MediaType('image', 'jpg'),
);
request.files.add(multipartFile);
var response = await request.send();
if (response.statusCode == 200) print('Upload');
}
but this code is not working
if i use this code, upload only another data
upload things
then json type is this
json type image
i want upload images files ...:(
i use this to send picture with formData
var head = Api().bearerHeader; ////just bearerToken
var request = http.MultipartRequest(
'POST',
Uri.parse(
'https://c.....'));
request.files
.add(await http.MultipartFile.fromPath('TITLEOFFORMDATA', imageFile.path));
request.headers.addAll(head);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
String varo = await response.stream.bytesToString();
}
This is how you can send image to your server with MultipartRequest with http package
try {
final uri = Uri.parse(your_url);
final request = http.MultipartRequest('POST', uri);
final multipartFile =
await http.MultipartFile.fromPath('Image', 'your_path_of_image'); // Image is the parameter name
request.files.add(multipartFile);
request.fields['userId_if_required'] = value;
final response = await request.send();
if (response.statusCode == 200) {
print('success');
} else {
print('Something went wrong');
}
} catch (e) {
print('Something went wrong');
}
How to upload your image to a Django rest API server
this will work for sure, let me know if you have any issues.
Please be sure to add the necessary packages to your pubspec.yaml file
image_picker
http
if there is some I missed please ask me or add it and add as a reply
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'dart:io';
import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart';
final _picker = ImagePicker();
File? _image;
// use this to send your image
Future<void>uploadImage(filePath) async {
// your token if needed
try{
var headers = {
'Authorization':
'Bearer ' + "token",
};
// your endpoint and request method
var request = http.MultipartRequest(
'POST',
Uri.parse("https://api.imgur.com/3/image"));
request.fields
.addAll({'yourFieldNameKey1': 'yourFieldNameValue1', 'yourFieldNameKey2': 'yourFieldNameValue2'});
request.files.add(await http.MultipartFile.fromPath(
'yourPictureKey', filePath));
request.headers.addAll(headers);
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
print(await response.stream.bytesToString());
} else {
print(response.reasonPhrase);
}
}catch(e){
print(e);
}
}
// Use this to pick your image
Future<void> _openImagePicker() async {
try {
var pickedImage = await _picker.pickImage(source: ImageSource.gallery);
if (pickedImage != null) {
setState(() {
_image = File(pickedImage.path);
});
uploadImage(pickedImage.path);
}
} catch (e) {
//print(e);
}
}
I have a Django API where a user is able to upload a file through a post request with the following body:
{
"file": *attached file*
}
In Django, the file is gathered from the request with request.FILES['file']
The request has to be sent from flutter (dart) code. I have tried a few ways, this is the function from my latest attempt which shows an error - because the "file" is not in the correct format.
static void uploadProfilePhoto(File file, String fileId) async {
Uint8List fileBytes = file.readAsBytesSync();
var response = http.post(
globals.baseURL() + "/upload/",
//headers: {"Content-Type": "application/json"},
body: {
"file":base64Encode(fileBytes)
}
).then((v)=>print("v: "+v.body));
}
Any idea in what format the "file" should be sent from flutter? Else is there any other method which might work? Thank you in advance.
in flutter use
import 'dart:convert' as convert;
import 'dart:io';
import 'package:http/http.dart' as http;
#override
Future<Map<String, dynamic>> sendFiletodjango(
{File file,
}) async {
var endPoint = url;
Map data = {};
String base64file = base64Encode(file.readAsBytesSync());
String fileName = file.path.split("/").last;
data['name']=fileName;
data['file']= base64file;
try {
var response = await http.post(endPoint,headers: yourRequestHeaders, body:convert.json.encode(data));
} catch (e) {
throw (e.toString());
}
}
in python django use
from django.core.files.base import ContentFile
file = response.data.get("file")
name = response.data.get("name")
your_file = ContentFile(base64.b64decode(file),name)
model.fileField = your_file
model.save()
You can try multipart/form-data to upload files from Flutter to the Django server using HTTP post request.
From flutter, you can send multipart/form-data request in the below shown way.
Future<Response> uploadFile(File file) async {
Response response;
var uri = Uri.parse(url);
var request = http.MultipartRequest('POST', uri);
request.files.add(await http.MultipartFile.fromPath('file', file.path));
var response = await request.send();
if (response.statusCode == 200 || response.statusCode == 201) {
print('Uploaded!');
}
return response;
}
You can find more about it here Dart MultipartRequest.
The Issue
I'm trying to upload images directly to S3 from the browser and am getting stuck applying the content-length-range permission via boto's S3Connection.generate_url method.
There's plenty of information about signing POST forms, setting policies in general and even a heroku method for doing a similar submission. What I can't figure out for the life of me is how to add the "content-length-range" to the signed url.
With boto's generate_url method (example below), I can specify policy headers and have got it working for normal uploads. What I can't seem to add is a policy restriction on max file size.
Server Signing Code
## django request handler
from boto.s3.connection import S3Connection
from django.conf import settings
from django.http import HttpResponse
import mimetypes
import json
conn = S3Connection(settings.S3_ACCESS_KEY, settings.S3_SECRET_KEY)
object_name = request.GET['objectName']
content_type = mimetypes.guess_type(object_name)[0]
signed_url = conn.generate_url(
expires_in = 300,
method = "PUT",
bucket = settings.BUCKET_NAME,
key = object_name,
headers = {'Content-Type': content_type, 'x-amz-acl':'public-read'})
return HttpResponse(json.dumps({'signedUrl': signed_url}))
On the client, I'm using the ReactS3Uploader which is based on tadruj's s3upload.js script. It shouldn't be affecting anything as it seems to just pass along whatever the signedUrls covers, but copied below for simplicity.
ReactS3Uploader JS Code (simplified)
uploadFile: function() {
new S3Upload({
fileElement: this.getDOMNode(),
signingUrl: /api/get_signing_url/,
onProgress: this.props.onProgress,
onFinishS3Put: this.props.onFinish,
onError: this.props.onError
});
},
render: function() {
return this.transferPropsTo(
React.DOM.input({type: 'file', onChange: this.uploadFile})
);
}
S3upload.js
S3Upload.prototype.signingUrl = '/sign-s3';
S3Upload.prototype.fileElement = null;
S3Upload.prototype.onFinishS3Put = function(signResult) {
return console.log('base.onFinishS3Put()', signResult.publicUrl);
};
S3Upload.prototype.onProgress = function(percent, status) {
return console.log('base.onProgress()', percent, status);
};
S3Upload.prototype.onError = function(status) {
return console.log('base.onError()', status);
};
function S3Upload(options) {
if (options == null) {
options = {};
}
for (option in options) {
if (options.hasOwnProperty(option)) {
this[option] = options[option];
}
}
this.handleFileSelect(this.fileElement);
}
S3Upload.prototype.handleFileSelect = function(fileElement) {
this.onProgress(0, 'Upload started.');
var files = fileElement.files;
var result = [];
for (var i=0; i < files.length; i++) {
var f = files[i];
result.push(this.uploadFile(f));
}
return result;
};
S3Upload.prototype.createCORSRequest = function(method, url) {
var xhr = new XMLHttpRequest();
if (xhr.withCredentials != null) {
xhr.open(method, url, true);
}
else if (typeof XDomainRequest !== "undefined") {
xhr = new XDomainRequest();
xhr.open(method, url);
}
else {
xhr = null;
}
return xhr;
};
S3Upload.prototype.executeOnSignedUrl = function(file, callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', this.signingUrl + '&objectName=' + file.name, true);
xhr.overrideMimeType && xhr.overrideMimeType('text/plain; charset=x-user-defined');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
var result;
try {
result = JSON.parse(xhr.responseText);
} catch (error) {
this.onError('Invalid signing server response JSON: ' + xhr.responseText);
return false;
}
return callback(result);
} else if (xhr.readyState === 4 && xhr.status !== 200) {
return this.onError('Could not contact request signing server. Status = ' + xhr.status);
}
}.bind(this);
return xhr.send();
};
S3Upload.prototype.uploadToS3 = function(file, signResult) {
var xhr = this.createCORSRequest('PUT', signResult.signedUrl);
if (!xhr) {
this.onError('CORS not supported');
} else {
xhr.onload = function() {
if (xhr.status === 200) {
this.onProgress(100, 'Upload completed.');
return this.onFinishS3Put(signResult);
} else {
return this.onError('Upload error: ' + xhr.status);
}
}.bind(this);
xhr.onerror = function() {
return this.onError('XHR error.');
}.bind(this);
xhr.upload.onprogress = function(e) {
var percentLoaded;
if (e.lengthComputable) {
percentLoaded = Math.round((e.loaded / e.total) * 100);
return this.onProgress(percentLoaded, percentLoaded === 100 ? 'Finalizing.' : 'Uploading.');
}
}.bind(this);
}
xhr.setRequestHeader('Content-Type', file.type);
xhr.setRequestHeader('x-amz-acl', 'public-read');
return xhr.send(file);
};
S3Upload.prototype.uploadFile = function(file) {
return this.executeOnSignedUrl(file, function(signResult) {
return this.uploadToS3(file, signResult);
}.bind(this));
};
module.exports = S3Upload;
Any help would be greatly appreciated here as I've been banging my head against the wall for quite a few hours now.
You can't add it to a signed PUT URL. This only works with the signed policy that goes along with a POST because the two mechanisms are very different.
Signing a URL is a lossy (for lack of a better term) process. You generate the string to sign, then sign it. You send the signature with the request, but you discard and do not send the string to sign. S3 then reconstructs what the string to sign should have been, for the request it receives, and generates the signature you should have sent with that request. There's only one correct answer, and S3 doesn't know what string you actually signed. The signature matches, or doesn't, either because you built the string to sign incorrectly, or your credentials don't match, and it doesn't know which of these possibilities is the case. It only knows, based on the request you sent, the string you should have signed and what the signature should have been.
With that in mind, for content-length-range to work with a signed URL, the client would need to actually send such a header with the request... which doesn't make a lot of sense.
Conversely, with POST uploads, there is more information communicated to S3. It's not only going on whether your signature is valid, it also has your policy document... so it's possible to include directives -- policies -- with the request. They are protected from alteration by the signature, but they aren't encrypted or hashed -- the entire policy is readable by S3 (so, by contrast, we'll call this the opposite, "lossless.")
This difference is why you can't do what you are trying to do with PUT while you can with POST.
Using POST method it inserts a randomkey as child. I just want "Name: Sudarshan" to be the child of UserList.
Can anyone point at what am doing wrong here.
return pplx::create_task([]
{
json::value postData;
std::string MY_JSON = "{ \"Name\": \"Sudarshan\" }";
postData = json::value::parse(utility::conversions::to_string_t(MY_JSON));
http_client client(L"xxx.firebaseio.com/users/UserList.json");
string_t PathQueryFragment = L"";
return client.request(methods::POST, PathQueryFragment,
postData.to_string().c_str(),
L"application/json");
}).then([](http_response response)
{
if(response.status_code() == status_codes::OK)
{
auto body = response.extract_string();
//return std::stoi(body.get().c_str());
}
return 0;
});
Image
The POST request automatically creates a chronologically incremental key name for you. If you want a specific key name, do a PUT request instead.
I am trying to create a list in CouchDB 0.11 which responds with some html, I am having problems getting CouchDB to set the correct header, whatever I try, I just get an application/json response header. Here is my list function.
function(head, req) {
var rows = [];
var row;
while(row = getRow()) {
rows.push(row);
}
rows.sort(function(a, b) {
return (Date.parse(a['value']['last_logtime']) - Date.parse(b['value']['last_logtime']));
});
provides("html", function() {
var content = "<html><head><title>foobar</title></head><body>";
for(var i in rows) {
content = content + rows[i]['value']['last_logtime']+"<br/>";
}
content = content + "</body></html>";
return content;
});
}
Any suggestions what I am doing wrong?
well actually figured it out myself.
the getRow() stuff needs to be inside the provides function :)