I need to convert this C# code to JavaScript:
HttpClient client = new HttpClient();
string SECRET_KEY = "my_secret_key";
Byte[] bytes = System.IO.File.ReadAllBytes(#"c:\1.jpg");
string imagebase64 = Convert.ToBase64String(bytes);
var content = new StringContent(imagebase64);
var response = await client.PostAsync("https://api.openalpr.com/v2/recognize_bytes?recognize_vehicle=1&country=us&secret_key=" + SECRET_KEY, content).ConfigureAwait(false);
var buffer = await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
var byteArray = buffer.ToArray();
var responseString = Encoding.UTF8.GetString(byteArray, 0, byteArray.Length);
I tried do this in JavaScript:
var file = document.querySelector('input[type="file"]').files[0];
getBase64(file).then(
data => $.ajax({
type: 'POST',
url: 'https://api.openalpr.com/v2/recognize_bytes?recognize_vehicle=1&country=br&secret_key=' + secret_key,
contentType: 'text/plain; charset=utf-8',
data: data,
success: function (ret) {
console.log(ret);
},
error: function (ret) {
console.log(ret);
}
}
Basically, both are intended converting an image to Base64 and send via POST to an API endpoint.
The conversion works as expected in both cases, however I get an error in JS.
Error 400: Error loading image
I don't have access to back end of this API and I don't have support.
I think some requirements are different, maybe the format of the type or something...
did you debugged the file variable where you are getting the base64 format . first try that and if this is not working try the below one to convert file to base64:
const toBase64 = file => new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = error => reject(error);
});
to call above method use : toBase64(file)
once the post request is formed check in the postman tool . I hope it will resolve your query .
Related
I am trying to send a pdf file from javascript to a rest wcf service.
The service expects an array of byte with the following signature
The trick is in the byte array parameter, all the others are working fine
[OperationContract]
[WebInvoke(UriTemplate = "rest/{sessionToken}/ImportNewTemplate?commit={commit}&createApplication={createApplication}&templateName={templateName}&option={option}")]
[CloudMethod(Group = "02. Templates", Description = "Import a new template in the platform.", HelpFile = "ListPaperTemplate.aspx")]
[CloudParameter(Name = "sessionToken", Description = "session token", HelpFile = "ServiceAPIDoc.aspx?q=sessionToken")]
[CloudParameter(Name = "createApplication", Description = "Create a standalone application linked to this template.")]
[CloudParameter(Name = "commit", Description = "Commit the upload ? if true, the template will be imported, else the return just allow you to preview template description.")]
[CloudParameter(Name = "templateName", Description = "Name of the new template. Only valid for single pdf upload. If the files are zipped, the file name in the zip will be used instead")]
[CloudParameter(Name = "templateFile", Description = "Can be a PDF file, or a zip file containing a flat pdf + xml definition", HelpFile = "ServiceAPIDoc.aspx?q=templateFile")]
CloudObjects.TemplateImportation ImportNewTemplate(string sessionToken, bool commit, bool createApplication, byte[] templateFile, string templateName, string option);
this is what I use from the javascript end to send the pdf file
const file = e.target.files[0];
// Encode the file using the FileReader API
const reader = new FileReader();
var fileByteArray = [];
reader.onloadend = async (e) => {
const arrayBuffer = e.target.result,
array = new Uint8Array(arrayBuffer);
for (const a of array) {
console.log(a);
fileByteArray.push(a);
}
let ret = await dispatch('createTemplate', {name: this.newForm.name, pdf:fileByteArray, save:false});
await this.$store.dispatch('hideLoadingScreen')
// Logs data:<type>;base64,wL2dvYWwgbW9yZ...
};
reader.onerror = async () => {
await this.$store.dispatch('hideLoadingScreen')
}
reader.onabort = async () => {
await this.$store.dispatch('hideLoadingScreen')
}
await this.$store.dispatch('showLoadingScreen');
reader.readAsArrayBuffer(file);
And here is the code to send it to the rest service
let url = `${getters.getServiceUrl}ImportNewTemplate?templateName=${name}&commit=${save || true}`
const xhr = new XMLHttpRequest;
xhr.open("POST", url, false);
xhr.setRequestHeader('Content-Type', 'application/json');
let response = await xhr.send(pdf);
However every time I get an error from the service when it tries to deserialise the byte array.
The exception message is 'There was an error deserializing the object of type System.Byte[]. End element 'root' from namespace '' expected.
I have tried a lot of alternatives but nothing works.
Any suggestions are welcome !
Thanks
For those interested, the trick was to add JSON.stringify to the returned array.
So: xhr.send(JSON.stringify(pdf))
would do the trick
I'm trying to send image from front-end script to my server.
Front-end script:
var img_data = canvas.toDataURL('image/jpg'); // contains screenshot image
// Insert here POST request to send image to server
And I'm trying to accept the data in the backend and store it into req.files to be able to access like this:
const get_image = (req, res) => {
const File = req.files.File.tempFilePath;
}
What way can I do to send the image to the server and get the image like in the example above?
your img_data is a base 64 string, which you can send to server directly in a post request
e.g.
await fetch('/api/path', { method: 'POST', headers: { "content-type": "application/json"}, body: JSON.stringify({ file: img_data }) });
On your backend, you can convert this string to binary, and save to file.
var fs = require('fs');
app.post('/api/path', async (req, res) => {
const img = req.body.file;
var regex = /^data:.+\/(.+);base64,(.*)$/;
var matches = string.match(regex);
var ext = matches[1];
var data = matches[2];
var buffer = Buffer.from(data, 'base64'); //file buffer
.... //do whatever you want with the buffer
fs.writeFileSync('imagename.' + ext, buffer); //if you do not need to save to file, you can skip this step.
....// return res to client
})
You have to convert it to a Blob first, and then append it to a Form. The form would be the body of the request that you send to server.
canvas.toBlob(function(blob){
var form = new FormData(),
request = new XMLHttpRequest();
form.append("image", blob, "filename.png");
request.open("POST", "/upload", true);
request.send(form);
}, "image/png");
I have a node.js server, which uses express-fileupload to accept images. Now I'm working on the function to upload an image. But I don't want to use < form > since I prefer xhtml request for various reasons, but mainly because I don't want to redirect the user, after he uploads an image.
I have tried reading the picture as dataURI, sending it to the server, decoding it and writing it to a file, which didnt work and seemed to resource intensive and laborious.
//I used the dataString from the callback method and wrote it to a file using fs.writeFile
function dataURItoimage(dataString, callback){
const atob = require("atob");
dataString.replace("data:image/jpeg;base64,", "");
dataString.replace("data:image/png;base64,", "");
atob(dataString);
callback(null, dataString);
}
//User side code
avatarInput.addEventListener("change", (e) => {
const reader = new FileReader();
reader.readAsDataURL(avatarInput.files[0]);
reader.onload = () => {
avatar = reader.result;
tosend.avatar = reader.result;
}
}, false);
uploadButton.onclick = () => {
var request = new XMLHttpRequest();
request.open("POST", "/avatarUpload");
request.setRequestHeader("Content-Type", "application/json");
var tosend = {avatar: ""};
tosend.avatar = avatar;
request.send(JSON.stringify(tosend));
}
Is there a better way to upload an image, which the user can select, to a node.js server?
You can try this example. It worked for me. I hope it can help you.
Sending dataURL throw Ajax request:
const dataURL = snapshotCanvas.toDataURL('image/png');
$.ajax({
url: 'http://localhost:3000/upload-image',
dataType: 'json',
data: { data: dataURL },
type: 'POST',
success: function(data) {}
});
Receiving request:
router.post('/', (req, res) => {
const base64 = req.body.data.replace(/^data:image\/png;base64,/, "");
fs.writeFileSync(`uploads/images/newImage.jpg`, base64, {encoding: 'base64'});
}
So I did it this way:
var request = new XMLHttpRequest();
request.open("POST", "/test");
var fd = new FormData();
fd.append("file", avatarInput.files[0]);
request.send(fd);
I created a FormData Object, appended the image, which the user chose in an input called "avatarInput", and send the object to the server.
On server side I used express-fileupload to access the file:
app.post("/test", (req, res) => {
if(req.files){
//With the follwing command you can save the recieved image
req.files.file.mv("./file.png", (err) => {if(err)throw err});
}
res.end();
});
Using dropbox you can create a shortcut by dragging and dropping a URL into your Dropbox folder. This will be saved like this:
Using the /2/files/download HTTP API from dropbox will return an XHR response that looks something like this:
How do you parse this response so that you can grab only the URL and make that a clickable link?
Here is what needs to go into an Angular 1 factory. To use this, you would just call the downloadFile function from a controller and provide the path to the file in your dropbox account.
function downloadFile(filePath) {
if (!filePath) {
console.error('Cannot download file because no file was specified.');
return;
}
return $q(function(fulfill, reject) {
$http({
url: 'https://content.dropboxapi.com/2/files/download',
method: 'POST',
headers: {
'Authorization': 'Bearer {{access-token-goes-here}}',
'Dropbox-API-Arg': `{"path": "${filePath}"}`
},
responseType: 'blob'
}).then(
results => {
// data received from dropbox is binary data saved as a blob
// The FileReader object lets web applications asynchronously read the contents of files
// https://developer.mozilla.org/en-US/docs/Web/API/FileReader
var fileReader = new FileReader();
// function will run after successfully reading the file
fileReader.onload = function() {
var string = this.result; // store the file contents
string = encodeURI(string); // get rid of the paragraph return characters
var endPosition = string.indexOf('%0D%0A', 32); // find the end of the URL, startPosition is 32
var actualURL = string.substring(32, endPosition); // grab only the characters between start and end positions
fulfill(actualURL);
};
fileReader.readAsText(results.data);
},
error => reject(error));
});
}
I am trying to :
Send a zip file via xmlhttp to the client
then read the file using zip.js and render its contents
I successfully receive the binary of the file i.e. the success callback is called but I get and error when I try to do getEntries. I think the error is with the way of sending stream , please help.
Error msg :
Error in reading zip file
My client side code (using angular) :
$http.get(window.location.origin + '/book/'+bookName,{responseType:"Blob"}).
success(function (data , error) {
var a = new Uint8Array(data);
//var dataView = new DataView(data);
//var blob = new Blob(dataView.buffer);
zip.useWebWorkers = true;
zip.workerScriptsPath = '/js/app/';
zip.createReader(new zip.BlobReader(data), function(reader) {
// get all entries from the zip
reader.getEntries(function(entries) { //HERE I GET THE ERROR
if (entries.length) {
// get first entry content as text
entries[0].getData(new zip.TextWriter(), function(text) {
// text contains the entry data as a String
console.log(text);
// close the zip reader
reader.close(function() {
// onclose callback
var a = 0;
});
}, function(current, total) {
// onprogress callback
var a = 0;
});
}
});
},
function(error) {
// onerror callback
var a = 0;
});
})
.error( function (data , error) {
var a = 0;
});
My Server side code on Node:
router.get('/book/:bookName',function (req , res ) {
console.log('Inside book reading block : ' + req.params.bookName);
req.params.bookName += '.zip';
var filePath = path.join(__dirname,'/../\\public\\books\\' ,req.params.bookName );
var stat = fileSystem.statSync(filePath);
res.writeHead(200, {
//'Content-Type': 'application/zip',
'Content-Type': 'blob',
'Content-Length': stat.size
});
var readStream = fileSystem.createReadStream(filePath);
// replace all the event handlers with a simple call to readStream.pipe()
readStream.pipe(res);
});
It is probable that you might have already found a solution. I faced the same problem today and this is how I solved it in plain javascript:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'assets/object/sample.zip', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
// response is unsigned 8 bit integer
var responseArray = new Uint8Array(this.response);
var blobData = new Blob([responseArray], {
type: 'application/zip'
});
zip.createReader(new zip.BlobReader(blobData), function(zipReader) {
zipReader.getEntries(displayEntries);
}, onerror);
};
xhr.send();
The problem I see in your code is that you are changing the value to Uint8Array and assigning it to var a, but still use the raw data in blobreader. Also the blob reader required blob and not an array. So you should have converted var a into blob and then used it for reading.