A
A
Alexander Popov2016-03-28 12:51:53
JavaScript
Alexander Popov, 2016-03-28 12:51:53

What is the correct way to send the contents of the Canvas to the server?

There is a task - to implement the creation of a combined image (background, several inscriptions with shadows) and send it to VK on the community wall along with the text. This condition of the order is to make such an editor.

Now I also want it to work in Opera 11-12 (the appearance of shadows in different browsers is significantly different, at least in Opera and Chrome for sure, and it’s more convenient to calibrate for Opera, since I work in it all the time). But in Opera 11 there is no XHR2 and FormData, respectively, sending files natively does not work.

At the moment I have implemented the creation of the image. I also implemented for test purposes the export of the image to a Base64 string by the toDataURL() function and sending it to my own server as a regular form field (x-www-form-urlencoded) with subsequent decoding. Everything is great at this stage.

Next, I tried to make a POST request using the multipart / formdata method, read the standard, found examples, and sort of did it. At first, there was a problem that it was impossible to calculate the Content-Length in any way - for some reason the correct value did not fit, but then it turned out that if you did not specify it at all, the request went through normally.

But now I'm stuck at a very strange moment. The file is sent, PHP sees it. I have a string obtained from toDataURL() by trimming the beginning, and if I send it to the server and decode it from Base64 on the PHP side, everything is fine, the picture is correct. At the same time, I have two implementations of the decoding function from Base64, written in JS - I wrote one myself a long time ago, the second is taken from the network. Both give the same result (at least in terms of length). And this length matches the file size received after conversion on the server. But! As soon as I send the decoded string (with the usual xhr.send) - something completely different comes to the server. Moreover, when sending by different browsers, the size is different. But always in the resulting file some kind of nonsense is obtained.

56f8cc7d7d45f.png     976795     2016.03.28 09:17
56f8ccfa326dd.png     650807     2016.03.28 09:19
56f8ced2903ec.png     762761     2016.03.28 09:27


Here the first file was sent by Opera version 11, the second one was sent by Opera in Base64 and decoded on the server using PHP, the third one was sent by Chrome of the latest version. Of these, only the second is correct... Moreover, the lengths are very different. I kind of guess that the problem is that the browser thinks that this is text, and there is binary data. But the HTTP protocol itself does not prohibit them - why would a browser mangle them? Perhaps the browser is trying to convert the data to a different encoding?

I can't see the result of decoding from Base64 on the client - the console does not want to display it =)
Trying to diff by such volumes of non-text data?

Please tell me what is happening, how to deal with it, and whether it is possible.

I would like to get the image sent to the server in pure JS without a server proxy, and preferably with little bloodshed. Moreover, as I understand it, the goal is almost achieved - apparently there are some minor problems with encodings ...

UPDATE: Firefox still displays the result of the conversion to the console, where instead of half the characters there are squares. But this is of little use ... The most ridiculous thing is that all browsers receive different strings after conversion. 758708 characters in Firefox, 507068 in Chrome, 650807 in Opera. And the correct result (as with server decoding) is only in Opera (suddenly). However, at the time of sending, something happens, and the server still receives something different.

I need to send the file in a standard way (VK will not decode it for me from base64), but at the same time not force the customer to upload the image to the computer and select it in the file input of the form ...

UPDATE2: if the task is not solvable, tell me the solution though would be for new browsers. XHR2+FormData - send a picture as a regular file? On the other hand, if for universality you still have to write a PHP script that saves the image to a temporary file and sends it via cURL - FormData is no longer needed ... I wonder if it is possible to use FormData for normal browsers, and for old Operas come up with some - a hack that makes the string look like this so that after the "replacement", when it gets corrupted, it just becomes normal. But for this, apparently, you need to analyze the received files themselves?)

Answer the question

In order to leave comments, you need to log in

1 answer(s)
E
Evgeny Petrov, 2020-05-07
@kazsat

So much effort to describe the problem, but there is no answer (

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question