Get base64 image from public highchart export server - javascript

Is there any way to get a base64 image (instead of png, jpg, pdf) from highcharts public export server?
server: http://export.highcharts.com/
Edit:
what I'm trying to do, is render the charts on server side and store them as base64. I'm able to do that by setting up a small web server following the instructions here highcharts.com/docs/export-module/render-charts-serverside but that means I need to host this in some place, and I'm trying to figure out if that's something I can avoid.

Since this is something I wanted to do from the backend and without the need of rendering the chart first, I ended up getting the image from the public export server and then convert it to base64 from the backend using RestSharp to do the request (C#)
public static string Render(Well well, string type)
{
var client = new RestClient("http://export.highcharts.com");
StringBuilder json = new StringBuilder('the options of the chart');
var request = new RestRequest("/", Method.POST);
request.AddHeader("Content-Type", "multipart/form-data");
request.AddParameter("content", "options");
request.AddParameter("options", json);
request.AddParameter("constr", "Chart");
request.AddParameter("type", "image/png");
var response = (RestResponse) client.Execute(request);
return Convert.ToBase64String(response.RawBytes);
}

I don't see the option base64 in the dropdown. So probably the answer is no.
But you could get the png, jpg or whatever and use something like base64 online to encode it.

Very much late to post But you can get base64 from http://export.highcharts.com.
You need to pass below configuration in Request
let chartData = {
infile: CHART_DATA,
b64: true // Bool, set to true to get base64 back instead of binary.
width: 600,
constr : "Chart"
}
You can use below example
fetch("https://export.highcharts.com/", {
"headers": {
"content-type": "application/json",
},
"body": "{\"infile\":\"{\\n \\\"xAxis\\\": {\\n \\\"categories\\\": [\\n \\\"Jan\\\",\\n \\\"Feb\\\",\\n \\\"Mar\\\",\\n \\\"Apr\\\",\\n \\\"May\\\",\\n \\\"Jun\\\",\\n \\\"Jul\\\",\\n \\\"Aug\\\",\\n \\\"Sep\\\",\\n \\\"Oct\\\",\\n \\\"Nov\\\",\\n \\\"Dec\\\"\\n ]\\n },\\n \\\"series\\\": [\\n {\\n \\\"data\\\": [1,3,2,4],\\n \\\"type\\\": \\\"line\\\"\\n },\\n {\\n \\\"data\\\": [5,3,4,2],\\n \\\"type\\\":\\\"line\\\"\\n }\\n ]\\n}\\n\",\"width\":600,\"constr\":\"Chart\",\"b64\":true}",
"method": "POST",
"mode": "cors"
}).then(function(response) {
// The response is a Response instance.
return response.text();
}).then(function(data) {
console.log(data); // base64 data
}).catch(function(err) { console.log(err);})

Related

Alamofire upload JSON response not compiling

I'm doing an Alamofire upload to the server and want to decode some JSON that's sent back in response.
AF.upload(multipartFormData: { multiPart in
//do upload stuff to the server here
}, to: server)
.uploadProgress(queue: .main, closure: { progress in
//Current upload progress of file
print("Upload Progress: \(progress.fractionCompleted)")
})
.responseJSON(completionHandler: { data in
guard let JSON = data.result.value else { return }
print("JSON IS \(JSON)")
//decode the JSON here...
})
On the line where I'm guarding that data.result.value has a value (the JSON response sent from the server), I'm getting a 'Type of expression is ambiguous without more context'.
The code to send the JSON object from the server looks like this on the Node.js side:
app.post('/createCommunity', upload.single('cameraPhoto'), async function (request, response) {
// do operations to get required variables
var returnObject = {
community_id: id,
title: title,
members: members,
image: imageURL
}
response.send(returnObject)
}
Any ideas?
Since you already have a codable/decodable Community struct, try this approach:
AF.upload(multipartFormData: { multipartFormData in
//do upload stuff to the server here
}, to: server)
.responseDecodable(of: Community.self) { response in
debugPrint(response)
}

Send form data from React to ASP.NET Core API

I editted the whole question because it was very long and confusing.
Clear, concise new question
I was sending all data from my forms as a stringified JSON, but now I need to append a file, so I can no longer do this. How do I send my form data from React to an ASP.NET Core API in a format that allows appending files?
Old question
I have several forms working perfectly: I send the data using fetch from React and receive it correctly as body in my ASP.NET Core API.
However, I need to send files now, and I don't know how to append them since I am just sending all of my content in a strinfified JSON.
fetch("localhost/api/test", {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
}).then(result => result.json()).then(
(result) => {
console.log(result);
}
);
I tried sending a FormData object built like this instead of the JSON.stringify(body).
let formData = new FormData();
for (var property in body) {
formData.append(property, body[property]);
}
But when I send this object instead of the stringified JSON I always get null for all the values in ASP.NET Core.
I also tried sending this:
URLSearchParams(data)
And this:
let formBody = [];
for (var property in details) {
var encodedKey = encodeURIComponent(property);
var encodedValue = encodeURIComponent(details[property]);
formBody.push(encodedKey + "=" + encodedValue);
}
formBody = formBody.join("&");
And I tried different combinations of headers with every type of data encoding:
No headers
'Content-Type': 'multipart/formdata'
'Content-Type': 'application/json'
'Content-Type': 'application/x-www-form-urlencoded'
I also tried getting the data from ASP.NET with both [FromBody] and [FromForm].
I think I have tried every possible combination of all the options I have explained above, with no result. I always get null values in my API.
Edit:
Right now, I am not even trying to send a file. I am trying to successfully send common data in the proper format before trying to attach a file. I don't know if I should change the title of the question.
This is my API code:
[HttpPost]
[Route("login")]
public object Login([FromBody] Credentials cred)
{
// check credentials
return CustomResult.Ok;
}
The class Credentials:
public class Credentials
{
public string Username { get; set; }
public string Password { get; set; }
}
The object body from React looks like this:
{
username: "user",
password: "pass"
}
My whole question was a mess and, in my case, the problem was the for loop. However, I will try to explain clearly what I needed because there is a lot of missleading information online about how to submit a form to an API with React.
Solution
Backend
In the backend, accept POST petitions and get the data with FromForm. If you need to use credentials, it is probably better to pass them through headers instead of putting them as hidden inputs inside every single form.
[HttpPost]
[Route("test")]
public object Test([FromHeader] string token, [FromForm] MyDataClass data)
{
// check token
// do something with data
return CustomResult.Ok;
}
If you bind an object, the properties must have the same name as the ones you are sending from the frontend and must have a public setter.
public class MyDataClass
{
public string SomeInfo { get; set; }
public string SomeOtherInfo { get; set; }
}
Frontend
Send the data as FormData. To do this, you can follow this tutorial. That way, you won't need to worry about handling input changes and formatting your data before submitting it.
However, if your data is already in a plain JavaScript object, you can transform it in a FormData as shown below.
let formData = new FormData();
Object.keys(data).forEach(function (key) {
formData.append(key, data[key]);
});
Nonetheless, this is very basic and if you have a complex object (with arrays, nested objects, etc) you will need to handle it differently.
Finally, I used fetch to call my API. If you use it, it is important to NOT set the Content-Type header, because you will be overwritting the one that fetch automatically chooses for you, which will be the right one in most cases.
fetch("localhost/api/test", {
method: 'POST',
headers: {
'Token': "dummy-token"
// DON'T overwrite Content-Type header
},
body: formData
}).then(result => result.json()).then(
(result) => {
console.log(result);
}
);
A bit more time now. (10 fish caught.)
I notice from your code you had used the header "multipart/formdata", It should have a hyphen; "multipart/form-data".
On my API I am specifying that it consumes the same type: [Consumes("multipart/form-data")]
I am not clear what the .net core defaults are and whether it should automatically de-serialise the form data but specifying it should rule out any ambiguity.
With my code I am sending a file with some parameters. On the api side it looks like:
public class FileUpload_Single
{
public IFormFile DataFile { get; set; }
public string Params { get; set; }
}
// POST: api/Company (Create New)
[HttpPost]
[Authorize(PermissionItem.SimulationData, PermissionAction.Post)]
[RequestSizeLimit(1024L * 1024L * 1024L)] // 1 Gb
[RequestFormLimits(MultipartBodyLengthLimit = 1024L * 1024L * 1024L)] // 1 Gb
[Consumes("multipart/form-data")]
public async virtual Task<IActionResult> Post([FromForm] FileUpload_Single data)
....
Then on the client side it looks like:
let formData = new FormData();
formData.append("DataFile", file);
formData.append("Params", JSON.stringify(params));
fetch(apicall, {
method: "POST",
mode: "cors",
headers: {
Authorization:
"Bearer " + (localStorage.getItem("token") || "").replace(/['"]+/g, ""),
Accept: "multipart/form-data",
},
body: formData,
})
With the file coming from
const changeHandler = (event) => {
setSelectedFile(event.target.files[0]);
setIsSelected(true);
};
(from my React component)

Vue-Resource upload file to PHP

I am trying to send an image through a resource and recovery in a php file but I have not succeeded, this is my JS file:
//* AJAX *//
startAsyncNews: function(){
if(this.sendimage){
var formdata = new FormData();
formdata.append("file",this.contentnew.imageFile );
console.log(this.contentnew.imageFile);
}
// POST /someUrl
this.$http.post('controllers/newsController.php', {
data:{action : this.accion_new, data_new: this.contentnew , imgf : formdata}
}).then(response => {
}, response => {
console.log("error");
});
},
imageSelect: function($event){
this.sendimage=true;
this.contentnew.imageFile =$event.target.files[0];
}
When I use the console.log = console.log (this.contentnew.imageFile), it shows me the properties of the image correctly, that is, it is sending the file well, but when I receive it in php and I do vardump I get this object ( stdclass) # 3 (0) no properties no properties and with json_decode / encode I get it empty, also try
headers: {
'content-type': 'multipart/form-data'
}
But it generates the following error:
Missing boundary in multipart/form-data POST
You need to add all your data in formdata Object using formdata.append(key,value) function.
Then you simply send formdata
formdata.append('action ',this.accion_new);
formdata.append('data_new',this.contentnew);
this.$http.post('controllers/newsController.php', {
data:formdata
});
// or just if i'm not mistaken
this.$http.post('controllers/newsController.php',formdata);
object in http request data.
I don't know what this.accion_new and this.contentnew are, but this line:
this.$http.post('controllers/newsController.php', {
data:{action : this.accion_new, data_new: this.contentnew , imgf : formdata}
})
should simply be be:
this.$http.post('controllers/newsController.php', formdata)

Manage to download PDF stream with Blob in javascript

A web page (front) is calling a service which send a PDF stream as a response :
Here is the front code :
'click .btn': function (event) {
/.../
event.preventDefault();
Http.call(params, (err, res) => { // callback
if (err) console.log(err); // nothing
console.log({ res }); // print below result
const blob = new Blob(
[res.content],
{ type: `${res.headers['content-type']};base64` }
);
saveAs(blob, res.headers['content-disposition'].slice(21));
});
}
Here is the response from the server ( console.log(res) ) : { res : Object } printed in the console.
content: "%PDF-1.4↵1 0 obj↵<<↵/Title (��)↵/Creator (��)↵/Prod ..... lot of characters....%"
data: null,
statusCode: 200,
headers: {
connection: "close",
content-disposition: "attachment; filename=myDoc.pdf"
content-type: "application/pdf",
date: "date",
transfer-encoding: "chunked",
x-powered-by: "Express"
}
However, the PDF is downloaded with no content, it's full blank like corrupted ( But I can see the content in the string ). It works well with the CSV routes ( I send a csv as a stream and download it with the same method and I got the data).
I think there is something with the format %PDF ...% but I didn't manage to find something.
Note : With postman, it works, my PDF is saved, the page is not blank, I got the data. So there is something in the front I am not doing right.
I also tried with :
const fileURL = URL.createObjectURL(blob);
window.open(fileURL); // instead of saveAs
but the result is the same ( but in another tab instead of saved PDF ) blank page.
Any ideas ?
You probably forgot to specify the response type in your inital backend call - from the example you posted "arraybuffer" would be the correct one here, you can check all types here.

Response in file upload with Jersey and ExtJS

I have a method which save an image file in the database as a BLOB file. The method works fine, but when I get the callback in ExtJS filefield component, it always goes through failure function and I don't know what I have to respond to go through success function, this is my code:
Server method:
#POST
#Path("/upload")
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces({ MediaType.APPLICATION_JSON })
public ServiceResponse uploadFile(#QueryParam("id") Long iconId, FormDataMultiPart form) {
CatIcon icon;
if (iconId != null) {
icon = catIconBean.getOne(iconId);
} else {
icon = new CatIcon();
}
byte[] image = form.getField("iconBmp").getValueAs(byte[].class);
if (image.length != 0) {
MultivaluedMap<String, String> headers = form.getField("iconBmp").getHeaders();
String type = headers.getFirst("Content-type");
List<String> list = Arrays.asList("image/gif", "image/png", "image/jpg", "image/jpeg",
"image/x-icon", "image/bmp");
if (list.contains(type)) {
icon.setIconBmp(image);
icon.setType(type);
}
}
icon.setDescription(form.getField("description").getValue());
icon.setFileName(form.getField("fileName").getValue());
icon = catIconBean.saveIcon(icon);
ServiceResponse sr = new ServiceResponse();
sr.httpResponse = true;
return sr;
}
What I have to return in the code above?
Client:
uploadIcon : function(item, e, eOpts) {
var me = this;
var form = this.getDetail().getForm();
var valid = form.isValid();
if (!valid) {
return false;
}
var values = form.getValues();
if(values) {
form.submit({
url : myApplication.defaultHost() + 'icon/upload?id=' + values.id,
waitMsg : 'Uploading...',
success : function(form, action) {
me.onCompleteSaveOrDelete();
},
failure : function(form, action) {
me.onCompleteSaveOrDelete();
}
});
}
},
I write the same function, me.onCompleteSaveOrDelete(), in both callback functions to make it be called, that's the method which I want to be called in success.
Greetings.
UPDATE:
I did almost the same Alexander.Berg answered. The only difference was that I write #Produces({ MediaType.APPLICATION_JSON }) instead of #Produces({ MediaType.TEXT_HTML }), because I need Json Response. But when I debug in chrome and check the response, I get this:
In failure:
failure : function(form, action) {
me.onCompleteSaveOrDelete();
}
In action param, within responseText:
"{"data":"{\"success\":true}","httpResponse":true,"totalCount":0}"
But It's still going through failure...I think I'm very close, any help??
Greetings.
The fileupload in Extjs is more tricky, because it is using iframe and submit, not a real ajax request for uploading files.
Try this on Server method:
#POST
#Path("/upload")
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Produces(MediaType.TEXT_HTML)
public String uploadFile(#QueryParam("id") Long iconId, FormDataMultiPart form) {
(...)
JSONObject json = new JSONObject();
json.put("success", true);
json.put("msg", "Success");
return json.toString();
}
this is because the upload accepts Content-Type text/html,
see Example at http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.form.field.File -> Example Usage -> Live Preview
Use Firefox browser with Firebug plugin and on Net tab the following URL -> http://docs.sencha.com/extjs/4.2.2/photo-upload.php
Response Headersview source
(...)
Content-Type text/html
(...)
Request Headersview source
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
(...)

Categories

Resources