I am trying to save an image to a folder in PHP by decoding a canvas.toDataURL('image/png') coded image. The toDataURL gives me the following string:
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAXYAAAF1CAYAAAD8ysHLAAAgAElEQVR4XuydCbiOVff/lw...
which is around 43 000 characters long. I send this to PHP via AJAX. Then I tried to follow some answers online how to decode it but none worked as expected. The one that came up the most is the following approach:
$img64String = $_POST['file'];
$img64String = str_replace('data:image/png;base64,', '', $img64String);
$img64String = str_replace(' ', '+', $img64String);
$fileData = base64_decode($img64String);
Line 1 gets the original string, line 2 and 3 is to remove the first part and keep everything after the comma and then replace empty places with + according to documentation. However, the 4th line gives me a result which looks something like this:
FileData: �PNG IHDRvu���� IDATx^� ��U���eʔ! !
%��Pр$C*�FC��FD��&�(RRƷdJ�䯼Pʔyʐ�����?�s�9g�������ֺ.W�s�}��|
��߽�����8�?&fF�#�#��5si�#�dka�����f�i�?
���d�1'ݔ'�#�k���Ʉ]7��V&�...
Basically a string with a bunch of nonsense (?) in it. What is going on?
If there is of any help, here is the AJAX call:
form_data = new FormData();
form_data.append('file', newImage);
form_data.append('action', 'file_upload');
form_data.append('security', blog.security);
// Send to AJAX
$.ajax({
url: blog.ajaxurl,
type: 'POST',
contentType: false,
processData: false,
data: form_data, ...
What I want
Previously I sent the uploaded file itself but now I want to resize it first, hence I used the new approach. Previously I used this on PHP side which works fine:
$file_type = $_FILES['file']['type'];
$file_name = $_FILES['file']['name'];
$file_temp_name = $_FILES['file']['tmp_name'];
$allowed_file_types = array('image/png', 'image/jpeg', 'image/jpg');
if (in_array($file_type, $allowed_file_types)) {
$upload = wp_upload_bits($file_name, null, file_get_contents($file_temp_name));
$status = "ok";
}
I want to get my string into something that I can use in a similar way if possible.
Related
On the page you need to load in the input type file, as well as display this image in img. And then ajax request to transfer the base64 string to the server and there translate it into an array of bytes. Here is my view code:
$('#modalWindow').on('click', '#send', function () {
var file = $('#autoPicture').attr('src');
var formData = new FormData();
formData.append("base64img", file);
$.ajax({
type: "POST",
url: "/Home/LoadImage",
data: $('form').serialize() + "&base64img=" + formData.get('base64img'),
success: function (data) {
alert('Success');
},
error: function (error) {
alert(error.responseText);
}
});
});
Controller code:
public ActionResult LoadImage(Car car, string base64img)
{
var base64arr = base64img.Split(',');
byte[] picture = Convert.FromBase64String(base64arr[1]);
return View();
}
But when you try to convert crashes with the text:
The input is not a valid Base-64 string because it contains a character in an encoding other than Base 64, more than two padding characters, or an invalid character among the padding characters
Although if you use the site to translate base64 to image convert normally.
https://codebeautify.org/base64-to-image-converter
If you need an example base64 code write, I will give. It's just very big. I can give, for example, the beginning and the end of the code, according to my definition it is suitable or not. Well, in general, if you need an example, I will give. I do not understand why c # does not convert.
the second picture for which the method did not fit:
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAtAC0AAD//gBRRmlsZSBzb3VyY2U6IGh0dHA6Ly9jb21tb25zLndpa2ltZWRpYS5vcmcvd2lraS9GaWxlOlZ3LXNjaXJvY2NvLW1vZGVsbC0yMDEwLmpwZ//bAEMABgQFBgUEBgYFBgcHBggKEAoKCQkKFA4PDBAXFBgYFxQWFhodJR8aGyMcFhYgLCAjJicpKikZHy0wLSgwJSgpKP/bAEMBBwcHCggKEwoKEygaFhooKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKP/AABEIAKUA3AMBIgACEQEDEQH/xAAdAAABBAMBAQAAAAAAAAAAAAACAAEDBAUGCAcJ/8QASBAAAgEDAgMFBQQFCAgHAAAAAQIDAAQRBSEGEjEHE0FRYSIycYGRFEKhsQgVI8HRM1JicoKSovAWJENTssLh8RclNEaTs9L/xAAZAQADAQEBAAAAAAAAAAAAAAAAAQIDBAX/xAApEQACAgICAwABAgcBAAAAAAAAAQIRAxIhMQRBUSIyQgUUFWFxgZGh/9oADAMBAAIRAxEAPwCpJasnht51EYsHpWbjdZBjIwaUlorDoAfOvcU67PGeO jBd36Uu79Kvy2zKcdahKEdRV7GTi0VwtSKKPlpAYoEOoqVcVGBU8CK2zMVPhtmpZceeAgAcUilTtbhUyJATnyqLocVCafRo012AFogMUeKYg0xDj0FGBUYqRTSGmGq5HSjMdCHx404kz40i7QxT4UJWpGPiM0POT13oAArTctHnzFIDfpvQBEy7VUcYNX5AxQ7ZBqi 1NESB69aZqWfKnAzTJICuc0wSrXJnYAVGVx1osKK7DFB0qdthtUJBJqkIvBSDkZFWIrmSPxyKYL5GkU8xStPsrldFuOdJdnAopbNX3Qj61Q7sjpUiSSJ41LXwra 0KS0deoqAxkeBq/HcE 9kVLhJOuD8qNmuxaJ9GMRF 8xX5ZqXuM 46N FWmtUPukg1GLfu3BcFl8gcZo2sWlAray495cfGgdGRipyfhVhEVFDLIynyz0oGkkxucg lJOymkiMKxGQDj4UgKkRyoI86kXlPVQfWnYkViCPCkCfGrLFM 4B60yKp8vpRYqK TTjJq0Y0A2HX0phEgOzD50Wh6siXmpz51bEKFQQQDUckRPRganZF6srqwz0ouYDJFC0ZU74 tLfOBTEJzVN19qrbKR5fWq7KfOmiZEBGOlIUZWm5aZCHVyuR4Go3HrR8tCVoKIGUmh5anIoSKdktGSEdGFYUhIR1FErjB8PSsdzdRFjzGaIIh6ikHzRA7dKWwULuVPhil3JQ7b0 afnNPZhSEAw60Y6bjNR85pBzSARjGdgPnURiIqfn9KYuPKhSaBpMg7o04VhU Ty83KeXOM GaXgD0B6bU9xaIiHXcU MZI6VJgVIIJRH3vdv3f87l2pboNGQE5Wki58cfKjOKQA9KHIFEkgSPHtNvnpUk1ipAeKZTnqD4VXz45OaLLEdazbd2maLWuUQSxPGwBbIIzsdqIOQMHB IomUnxoDE3nVp2uSKrocnPQJj4VGVJOORT8DTmJhQMjDrmqFbBaNs/wAlUbxt17sj5UZU0uYinYqK5HmKEirBYn3gKA7DoPpTsVEJWm7lj0FGwFNlvAmhsEi3gjwp6Mo2NwRTAA9WArn2OhxEDRBtsFfnSGFbHsuPOrCmLGDEoPnzVLlQ1AjByNzT7edTfZ4w27HlPTB6VFyhSykMSOhBprImDxtDfSltRLEWOzDpnemdGRsMRv0OdjRsmTo0NtilgULDfrTqzKRiiwS k0coRSrAMhOcetWzeCeMxzAPvkb4xWMJz12x60ahWGeYZqWky02uC4lvC4OCUY9N8gUTPdWpCpNzR GOlUVyDsalDGNcgnJpOxpr0NKedi3Jgk52phyr93PxFSLcj2ecDCjbanW4iIwY1J8xkUbMKQcFxEAyyR5Rhg4FDN9mbmaMuh6heuPSo5COYlFIU9BUZYg9ARmhfQfwXKfM1JFB3pYCQLgZ3FRiQgkjb4UHMQ2cH5Gq2ZGqLUdhNIGPMgI6Bj1 Bqq8bqWVtivUZpxK4zyswHlQu5brkmmpSsbjEAxmmKmjWTlYHAOPA1PHcxMQssQC77jqKN2hKCfsplPMUJT0/CpGbBODt60Jk/pCq2YtERGNvSh7s1Lz uaFpGz1Ao2YaINHkJ2JJqpeavZWLct5cxB/5g9pvoK0i/1m vCeecpH07qI8i/xPzNYyPfIUbncgV5s/MX7Eepj8B9zZu1xxXaBiLS2nm9Wwg/jVCfim JBiihhXyI5zn4nH5Vr9tHzsMbg7dCN6susIR2csiKAwI3GD8uvpXLLysj4s64eJiiroy8XE qF1QSROxOAnc5Y/DG5r0Dh7ReJdVjTvtFltsjm72RlQY9VJ5h8xWZ7KOGrrR9IaTUIYor68mEipyDvYUwAqO3n4kDYZxuRXgXbR2gX/F3Ed5pllPNBw/YyNBHAjFROynDSyAe8SRsDsox45J6sSmuZM4c8scuIR4 nt15HoGkEjiDjLQbF196JJ1lkH9kHP4Vhp POyq2k/bcS6nf8q4KW1m4UnzBKD865aZACe6VRj0xUTAuFGdycda2tmKSOoH7Xeyq1OF0TiS68mMQwfrMPyok7cuzBDgcJ6yR5mCIn/wC6uZrwZuAig5GFGKrcjMcKuSdh8aOfolXw6zsu3DsrmPLJoep2o85bBCP8MhrceGON yriW4W206/01LljhYbqM2zMfId4ACfQE1xYunxA 2ZD8DQXdvFHbkqjFicDJzU2/TH Pw7V7SdO1rQIpbzh7g3RtY05Bl WSUXMY8SYh7w/qkn0rx2PtTSYgvwvo4B8UuLhf ete7Hu2/XuCp4NN1Mz6xoOyi1ZszQDzhY/8B2225c5r33XuBeEO1nRxxNwhcWkOoz5LXCJ7EsgG6Tp1Vxtk 8M59oYq4z14kEoX k8nbjmzuSB q5rVvO3vBIP7siHP94VZtNZnuWBtLq0kJOBHdRdw3plgxX8RWp8RcOX3D pvpusW0um3a 0E5QySL05kb7wPmD8QDtUcUYhA/aSDH3sgirek/bRknOD6T/0b5d69NYSxw6vYS20jjmX2tmHmudm RNW4NTs7sBre5iIxnBblI talp tXlnbm2YxXVi 7W0yd5E3ryHofVcH1orjTdM1qMfqm4TTrvqLO8kzbu3kkx3T4SZH9KsnHNj5j S/wDTeM8GXiX4P/qM3dcTaXC7p37zMhw3dRlhn tsKnstYsL1gkNyokP zk9hvoa85 y3 ki3sNbtbi3vY1ZpVdOU5BGD5MpzkMMjbrUrKOVyR1wxB61y/wA5NS5SOz n43Hhuz08 yfI RFBcXEVtEZbiaOGIffdgo/GvNTxHe2ASK3uWUsPZQ4YAb779KoXlxJqJFzPLJMxHvSHOPQDw ArV aqtLkxj/D5bU5cG8XnGOlwuEgM14xO3dryg/M/wrHTcaykHudPjUeBklJ/ID861JB3ftuFBxjfqOvSo2Zi2EPtMdvyrF VkfTo6o Fij2rM9ccXao5YB4Yd9u7iBx8zmqz8QaoHAa/n5vRsD6VjAilcg78ucnbfH/SnnB2YkMxGDt1P8Kzeab7bNVgxrqK/wCGTXiTWGljJvX5B1yi7/hvVyLi3UI1KSQQTsDgv3ZH4A1q/eEDoMqOvhVqODMaks2SATgkU1nyR5sl Pjl 1GUxGjYVVYYyMjrR yRgEquDkKMA1D7uwPtHc48KQHN8vCuejo4JAqo8kiEgk82D0Uelem9kHC9jqd0dVe/sLy5tCGjs7eZZjbMchZJADs2x5R4bnr00HROD7jjKeOzSYWtgsqtc3GMkKATyoPvMfoOprpLg3TNF4Y0aLTdCtobO0U5bfLyv4vI/VmPn4dAANq6/Hxpfmzi8vLxpFmTtrGVFCyzB368wj5P3msBxB2acJ8RTST6xw9p09zIeZ7iIGCVj5l4ypJ9TmtqaY8mWK7/AM05FVZLvk8a6GzgPJdV/Rv4Wui76dfazpzN0USpcIPkwDf4q06 /Rh1SGQPpnEtjOAcgXVpJCf8JcV0N sMeNUn4othNqMKd8JdPZRP3ilECHo4YA5Hy/dlWM5tvP0euObecTwNol06sHAjvCu4ORs6D861 67E 0OCN0/0beZCwcm3uYZdwCPB/X8q7FTVQyhopi8bAFWwRkfAgH8KkGpZ6lT8QDT2Yao4Wv8As9420/JuOFdfjA6utlIyj5qCKPg/9TaPr4n7RNC1W906NCFtwXg9vPVzgEjHgCN/pXdR1RIo2kkMcaICzOTyhR5k15rxpx5falHLZ6Q721kwKvMxJklHjjPuqfqfwpq5cCdR5Na0jj/sIu7WK0m4X020jkAVnk0xWaPPm OfbzGa0bW K9I7O 0pdX7ItQe90a4t1l1GyaYtbyNzkd2pbDZAwQdypbrgla3TQ yMa6Vm1ZYtPs23GIV75x/RXbHxP0Negw9i/Zw1nHby6AkpQfyz3EyzMfMurD FS6TKTbVm1PDw72ncGWM93B9o0 gW4t5fdlgLDqGHuupyDjbYg5G1eK652C8VRaix0bVdEvrHOIlvGkgkxj7wVWUn1GB6DpXtXCnDdlw7osWmaDcz2unQSSdxC7iYIC5JwXGcFuY9T1rNhL1XjYXNvJyE4DwlScjG5DEeXh4UKTXQ2k zl49ivaBbuBHZaUxH3k1IgfQoKuxdknHpUCax0dGH3zqO59DhK6dE12B 1tYZQOvdy7n4BgPzpGdB/K2l1H5lU5x/gJzWizS mbww HP1jwFxrDaJYatp2g6lpSnItrjUGzEfOJxHzRn qcHxBrGa32UasHd9NeFox7sNzOC4GOnOFAOPMgZrpETWUjhRdIrk45ZMA58sHBzUkliG 4jD0OKjJGGV3JcmmKc8KqD4OJOIOD9f0ySWfUtEvUUDHeJH3qYB29pMj1rGWwzAqBieT2T5/TrXcr6fGDkK0Z8x/EVhNX4N0nVx/r n2d2fBpIlLD 0N6xl4yfTOmPmNfqicdzKXYl uM eKrGM55l2OcH4eFdLa12MaJchmsRcWLnf9lIWXPwbNeccS9kWv6arS6e0WoRLk8o/Zufhk4/EVi8E4nRHyscvdHmNwUUALkqPxOKgeRmdi25PkMfPFWbu0ube6e3vYZYLhD7UUqFXHyP51CYeVCD7oznJ2BFZ1Rvd9A4VhygHkxv658aIs2waRhgYHtGilTMChS4JzjB38qa3RHjDSAFz13OM m9AGWX2sY90dNiMUmIPUtsMDrUaSpK InLN443x8aBmV5GSNy5HgB psVGaveNZ DeCEm01UOpXtw8cDsvMsYUDmcjoSMgAHbJycgYPlzcZcUy3f2qXibVY5yeYEXcgx8gcAenSth49El5p3DVtGFZ2muEUA7c5MX8RW5fqSw0fhZ7aLItpZLW7tbqWNBI13G3JdWUrdcsjiRR0YR eQO6D/FHmZF b/yZvsW7YL681SDQOLJkme5PLa3oAXnfwRwNsnoDsc7HOcj2q9mZSd64q1ixm0y9VCRBqCuWeJBy/Z5A55Mf3fCuuuFdUfifhXS9UgjLyXVuryKgzyvj2h9c1TM6LL3RGdz9aCSZGn70pGZVPsuVBYfA9albR7qQ78qnyNDJoN9sV5W2HjSGIXzHqx tSLfHzqnJpGoR7mFj8N6qvDdRHDxSD4rQAXEIvtUEFtbyxpa 9KXOMtnbYbkCrWiaZZaayykfaLkbiWQbKf6K Hx61jxO6n2sipUuyOtO30Kl2bdHqGTkk5q3BfjmX2vGtNS79TVmO7PgaQza7XUAlrGOboD ZrH8Qcf6FwvAk2v6pbWQccyI5JkceaooLEeoGK0bjLideGOD7zWJVEjQRqkMR6SStsgPp1J9Aa4 1XUr3WtUnv9UuJbq8uH5pJHOSxPh6DwAGwGwpoDtJP0juAll5De3zL/ADxYPy/nn8K3XhPtY4L4omSDSNespblzhYJGaGVj5BJApb zmuAIBbQlU1DTXRW2D5dWHqM7H6VcvtAVoe/02XvYiCQrdT8D 6gKPpae6lQq3KwOxVh GDWndpesf6E8H3uu6fo0t 9qULwW85gCoTgu2AfZXOT7J89hkjmLsB7aL3RdWteHuLLk3OlzsIoLu4PM9sxOArsdzHnbf3eo2BFdh8ltPEQ0MbI6lWRlBBB2KkfUGgDxLgPtv4j4q1g2NlwQbpeTnLxX O6AyfaJjC74wOnz61sMfbboCtjWdC4l0xcKxnl08vGVYEhg0ZJwQCengfKtf4o7FLiz1OXVOzvUIbGR1OdPu5JEhUnxjkjPMoHgpyB4EDYaHrvCfbA98TJw9HcWShUXu7i3nYhUCZy7ZwxyxGOrHGKu4k8nvukdqHAurMEtOKNMDk47u7k zPny5ZApz6YrcFjhuIlkiKSRsMqykEEfGuPeKtF7QNT4I0TRZ Br S8sZ5Xkc2UTRqrAYEfKckk83NzZ6LWvcM9kXHnEd8NMPD0uiwY5prq7EltCB4eyCec ij44G9Fr0wp 0dF9pOi8NXBni4g4h0i2jCs8MtxPHHdWj HLj UQ9OUgEeZrmWcQGWT7Jcpd26u0aTxgqsoBI5lDAEee9ep6f jFpmkWwveMeLIobZGUOsMQjXJIAXndsZJIAHLnJGKo9p3D3DGhWOnrwfDfIiN3c7yKVWbbPMA4BLbbkALjArHNFNbLs6vGyOL1fR5tylnLEnGxB8qIRcoAjBK/0aYpK9wx7xwcAcpGOU NGsbqPvE pIrlfB3rkv8A2VeQqzsw 6q4RM/AVHJHIIyWkjjiUb7hQKy4VT1Yk QWsTxDoj6vBEsczRd0S2GjLKc frWapvkcm0uEYK61K3Op6IsN8n r6gkneBOZI8kAtuN8YU49K3bUNJv24j4p06HWtNv4JR sma1X2L6VZFUOQ3sK3O5QAdSTg43rzDVOHdVtQ bV5oh/tbcc4 O24 lbFY8f29xw9 p IYJ7ea2sjawXNjFGkhYTJKhkBAyAU388 Fd LVKk7PLzbOVtUQdocmoF4m1IRXPciKzt7xESIhIQV7lkQAAruPPbqa2LhC6k1Ls8k0u31C90 602 ZkltJjG4RskdCMj2m2rROPuJrTiXii 1KysP1da3NzJdmAzGUmWQgyMW9WGQBsAcb7k64b 4juZZbSeaAv1MblSR64qn3wZr 57Rba5x9pYA07ju9dR0S8XvR/i5hWVtu1XtOsgO9Xh/VQux5oFVm/ulDXhcev6ugwt/cEerc351Yi4r1iM 1cCT0eNf4UvyKqJ0La9vuv2oA1ngMSY96SyuZFHyBDj8ay9p kXwnIwj1bR9e0 Q9fYjmUfip/CucYON9QQ5khgb qCp/Or8PHpcBbu1dk8QHDA/Iilb BrH6dP2faz2aarhTrsMDnwu7SWL8QpH41mrWbhHWT/AOVa9o9wx8IL6Mn6Eg1yUOIeG7v/ANXpsSk9S1sB KnNELbgy9B5GWAnxWdkx/fBo2 oNfjOubnhO4A57Ys69fdyPqKwlzZXlk472NuXOMiuc9M0RLYA8PcT6nZnqO4nB/4GWtmsdV7Q7Vkhg46aa3JAYX4Mns Pvq3h60WmKmg/0htUDcL8OachObh5b2RfRVCJ LPXlfCPd2MU2rtELiS0kQ9yyk80ecOfLod63z9IOdLq 0SaHkMX2OVAYzlciXJx/eFafw7qUdvw4ggnFtewXJfvZVBjKEbqR1OfKqQi7eWqtBbWpl72xe7eQyHfngI5lPocbeh FYzh24VbiayV2khYGWBm6n GRkH4VlkubaW5iu7C1X7LLKe7tnBWBiABIQnioyGx55rASS2sV1pUtisiCN2icSEZHtZ/eaGgTFxXYouLqIjOQGwMZB6NXafYRxTJxJ2a6Pd3Mhe6jj zzsTkl4zyZPqVCMf61cg6woewuoyw5eRsLud1Of3AfKvdf0QrwtwjqlszEiK LAeQaNP/AMVK6GzpBJt9qwGvcf8ADXD9w9vq2sQwzIQrokbymNj0D8ikKfQ4rVu2firU FOBZ7nQ7aeS/uH zJcpC8iWakZaVuXcHGy HMc FcXT6nOiSxfb5gjlneMXU6hyTk5DDck77 NNAdt/ OXZ8IGnHEhMCMEaRbG4KhjnAJ5MeBqvJ kB2cp/7hlb rYTn/kriW 1GWWIRW1xHFa yGSOUgSEAHmYE5JGcZPltVIMp6yL/wDJn86qhHVfad258G63pVvpthcalMWvra4af7GUSNYpVkPvEMSeXoB9K8v13i DiWSO30xLkWNooYyTLh3cjlHjsOUDxOfPz8r0 0udQvUtNPt5ru6kPKkUCGR2PoBXsFv2ftwrwqo1yXu KLydJPsCSBhbWwU/yvk5JBA6j61OWVY6NMCvIjV762kuzCwuXhmhJKODkHPUMvjSCy43Vc/0XGPlnes22mS7FSSPUUH6snGR1 JzXDsj06XZsyLaA4Jlwejc29EgtgzYBYEco5gW Y8j6/GseXK5Crgep3wKTS8zFtj036Z8fCoErL6C2GPYdd hJ/yaCZIZ8LMiOgP 0AY49M1UUsSD3igeTNnFSpIQNpGBxkco9aQCFjYxSExWkEbnqY4VB/KmmtYZU5HjR1B6PGrDHzFSc7ltyc4wTnOf87VOGd p6eH8aKC6MLccPaTPvJp1kQc792EP HGaxl3wVoUyoY4ZIDygHupWOT5 1n6DatyWN YMzLgenj8aIxIdsDGAB57CmpSXTJag 0ecy9nNtJvbXtwufB4lbH0IrH3HZtdrnuL23k9HjdD vVFVg/syIR5EDFIq65YMCSPPH0qlmmvZLxY36PGLngLWYTgQwy5/wB3MpP0ODWLueGNYtyRJp10MeIj5h Ga94ZnyRkjby6/wDWowpb3WQDGeoFWvIkuzN PB9HPMtrPbt 1jkjI/nqV/OrNvqup238hfXKgeAkJH06V740XOjZXmHQ8wyCPnWLm0XT7hj32n2jHxJhA tWvJvtEvxvjPGtR1zUNSto4b6UTLGzFSUGRzAA7j4D6VmuA9cls49R0YrE1vqyLCwlxgEH16Z6Zr0W 4c0u7TluLC2wPZVkXu2A9CuPCtX1Ts5Vw76ZcujfdjnGQf7Q3/CtIeRH3wZz8d uS1bJcC20yxuHWKaTULqFXABETNHiMLkbLkL9TWn6rNNdajZQXNoLa Rz36gYJOcDI8DgVkbwcW6ZaNb3EE0sBYOJBGJt1GA3MPEA NYjT9N1i5u5LkWF7cTyEkyNGep6ksfGtnOLVpmCxyTpoyOqXATT7gk45lIHqScf9a3r9HXj3S DxqsGr3It1nkjkjZgSDhXB/Na83v9H1ybCS6fchFOwROYE/EdagXhjWDgDS73fbeIioUo12W4yvo69l7fuF7Y/s721f1RXBP0qjd/pIcMsMSESjptAzfmK5Xj4R1pt/1fKo82ZRj8asw8Faq7LzrBGpI3MnN Qo3ivYLHN joGT9IPhO1kkkstCTvH95orGNS3xJxmsLrf6Q l6hCUk4Nsr5R7q3sERX6YNeRW/At0xHeXcCZ/mKz/wrP6VwnYWbKzg3Mwz7UvuqfML/AN6l5YrotYJPvg3PT 1HXbuwkGl6bp/C1rKcCPSrZYWdfMsACPlisQblpC7PlpGPMzMeYk ZzvnbqaQ09gAQpI8yucee9ELZVOGSTIO6qK5pTcnZ1xjGCpA9 MjIbJ3GNqJZ3xus2/kCaYxqJTzd4rDcbVIsKY3Z/nQO0ZbuHYjmK5z8Nqk7kZIwq IqRQQehHh7Qxt5/Cpo4JJA7IvPyDmbB6D4dTRRluyssWBuvKfCpBHzAg7 XpR759tuvTH76LJ5j7J tKkGzBWPlAICnbGcURLLjOAOvSkH9kjxHhiiLEDAUZo1QbMEZycbZJzvSZSTy5 VEWPQnceGKXMxGCMYGetFINmM3UZbPz/Oky5XGNzvv0owcDGc7Z NIAfzSc9TRQWwc55cxnB2yBt86JV5slkByOox1p2A 6o6daUaopwFCHyooLZGVQsQfe9R1PhQ8iEkMFAbYsd6s4XDOCvXGAcnp VCyjvAQcHIG4zS4C2QGLdjzA Pl/2pGMBjkOd nNzVY5UGNiBimJwBzZAG etAWVu7BAIJBHrSMAbflJPqelWOUAYB gpimTkswOflRSHbK7R xhuZcjG2xFCyRhs z0zkGrQjz0PXYbUwi/z0p0Kyv3fLuqYyMj4VH9lUnLFh4kHx9avNEh5SwHMpyCNsUxxsM5zvscUahsU 5VQCNuhx1yBQmNChHIQpGdvM1bKDP3SAaSxqB7W/jv8AnTSFZUCoGUAvtsPDPnmkQDgq3jsDVnkwMKcbZJzQEH3j1z4LVCsgdDyjcnxIU4 uah7rP 8/suR W1XHBCllGWHTOBUDvynHsj45pisyQh5ZpYyVIQKfdAyG8KiidJLoRPEhKg 1656jypUq5LZrXRce3jAU 0WwWO/kSKGaNYy7ADAXOMUqVNSdjcVVkwhUWzSsAQhG2MZBz4/KojEhRmCrjlyBjpk0qVGzFSEsK8xzjHMVHp/nFBOgQIMKSzlc4pUqpSYqQUkHsLytgnxKg7ZXp9aL7PvgORkdcdMGlSqrECYsMPaO fCm7hSV9c9fClSpoQlHMuBt1P0pih5iQ2D4bdKVKkxiAwAdsjxx60A3OPxpUqBgkkEYx9KZkICgtnP76VKnYhBjjqdt/wAadckjJPWlSp xDY6eR3piABkDptSpUAPjrv5UOfbYeWAM/ClSqvQhAZ32pjtSpUIQzpuRnw8RVdkBPRcdB7NKlQyl2f/Z
And the first picture has a very big base64 line, is it also off?
The problem seem originated from this line:
byte[] picture = Convert.FromBase64String(base64img);
If the base64img contains some header like data:image/png;base64, then Convert.FromBase64String() fails because the string is not fully formatted in Base64 format. Consider using string.Split() before converting from string parameter to remove corresponding Base64 header:
[HttpPost]
public ActionResult LoadImage(Car car, string base64img)
{
// split the header and content, separated by comma
var base64arr = base64img.Split(',');
byte[] picture = Convert.FromBase64String(base64arr[1]);
// do something with the image
return View();
}
If the content string contains characters other than ASCII or trailing padding ones, you should remove them like this:
string base64str = base64arr[1];
string processed = base64str.Replace('_', '/').Replace('-', '+');
switch (base64str.Length % 4)
{
case 2:
processed += "==";
break;
case 3:
processed += "=";
break;
}
byte[] picture = Convert.FromBase64String(processed);
Also consider using FormData object when passing image formatted with Base64 string:
$('#modalWindow').on('click', '#send', function () {
var file = $('#autoPicture').attr('src');
// note: if you send other form data, use 'serializeArray()' or 'serialize()'
var formData = new FormData();
// append other form contents here
formData.append("base64img", file);
$.ajax({
type: "POST",
url: "/Home/LoadImage",
data: formData,
success: function (data) {
alert('Привет');
},
error: function (error) {
alert(error.responseText);
}
});
});
Note:
The equals sign like = or == at the end of Base64 encoded string serves as trailing padding characters and not all Base64 encoded strings ended with them. You can see the reason behind padding here.
I am trying to make a post request through google scripts to amazon to collect information.
We are trying to get our orders to MWS and transfer them to sheets automatically.
I got to the last step which is signing the request.
A few things I wasnt sure about:
They say we use the secret key for hashing,I only see a client secret
and an access key id, which do I use?
Do I add the URL as part of whats getting signed? On the MWS Scratch pad they add this as shown:
POST
mws.amazonservices.com
/Orders/2013-09-01
Does it have to be on separate lines does it need post and the rest of the stuff. Its a little unclear.?
I read online that the sha256 byte code gets base64 encoded, not the string literal, is that true?
I tried to hash the string that amazon gave to me with an online tool and compare it to the hash they provided and the base64 encode, thing matched. I tried decoding as well, nothing matched
Can someone please send me an example that works, so I can understand what happens and how it works?
Thank you!
Below is what I have so far:
function POSTRequest() {
var url = 'https:mws.amazonservices.com/Orders/2013-09-01?';
var today = new Date();
var todayTime = ISODateString(today);
var yesterday = new Date();
yesterday.setDate(today.getDate() - 1);
yesterday.setHours(0,0,0,0);
var yesterdayTime = ISODateString(yesterday);
var dayBeforeYesterday = new Date();
dayBeforeYesterday.setDate(today.getDate() - 2);
dayBeforeYesterday.setHours(0,0,0,0);
var dayBeforeYesterdayTime = ISODateString(dayBeforeYesterday);
var unsignedURL =
'POST\r\nhttps:mws.amazonservices.com\r\n/Orders/2013-09-01\r\n'+
'AWSAccessKeyId=xxxxxxxxxxx' +
'&Action=ListOrders'+
'&CreatedAfter=' + dayBeforeYesterdayTime +
'&CreatedBefore' + yesterdayTime +
'&FulfillmentChannel.Channel.1=AFN' +
'&MWSAuthToken=xxxxxxxxxxxx'+
'&MarketplaceId.Id.1=ATVPDKIKX0DER' +
'&SellerId=xxxxxxxxxxx'+
'&SignatureMethod=HmacSHA256'+
'&SignatureVersion=2'+
'&Timestamp='+ ISODateString(new Date) +
'&Version=2013-09-0';
var formData = {
'AWSAccessKeyId' : 'xxxxxxxxx',
'Action' : "ListOrders",
'CreatedAfter' : dayBeforeYesterdayTime,
'CreatedBefore' : yesterdayTime,
'FulfillmentChannel.Channel.1' : 'AFN',
'MWSAuthToken' : 'xxxxxxxxxxxx',
'MarketplaceId.Id.1' : 'ATVPDKIKX0DER',
'SellerId' : 'xxxxxxxxxx',
'SignatureMethod' : 'HmacSHA256',
'SignatureVersion' : '2',
'Timestamp' : ISODateString(new Date),
'Version' : '2013-09-01',
'Signature' : calculatedSignature(unsignedURL)
};
var options = {
"method" : "post",
"muteHttpExceptions" : true,
"payload" : formData
};
var result = UrlFetchApp.fetch(url, options);
writeDataToXML(result);
Logger.log(result);
if (result.getResponseCode() == 200) {
writeDataToXML(result);
}
}
function calculatedSignature(url) {
var urlToSign = url;
var secret = "xxxxxxxxxxxxxxxxxxx";
var accesskeyid = 'xxxxxxxxxxxxxxx';
var byteSignature = Utilities.computeHmacSha256Signature(urlToSign, secret);
// convert byte array to hex string
var signature = byteSignature.reduce(function(str,chr){
chr = (chr < 0 ? chr + 256 : chr).toString(16);
return str + (chr.length==1?'0':'') + chr;
},'');
Logger.log("URL to sign: " + urlToSign);
Logger.log("");
Logger.log("byte " + byteSignature);
Logger.log("");
Logger.log("reg " + signature);
var byte64 = Utilities.base64Encode(byteSignature)
Logger.log("base64 byte " + Utilities.base64Encode(byteSignature));
Logger.log("");
Logger.log("base64 reg " + Utilities.base64Encode(signature));
return byte64;
}
Step 1, creating the string to be signed
The string_to_sign is the combination of the following:
The string POST followed by a NEWLINE character
The name of the host, mws.amazonservices.com, followed by a NEWLINE
The API URL, often just /, or somthing like /Orders/2013-09-01, followed by a NEWLINE
An alphabetical list of all parameters except Signature in URL encoding, like a=1&b=2, not followed by anything
The minimum parameters seem to be the following:
AWSAccessKeyId is a 20-character code provided by Amazon
Action is the name of your API call, like GetReport
SellerId is your 14-character seller ID
SignatureMethod is HmacSHA256
SignatureVersion is 2
Timestamp is a date like 20181231T23:59:59Z for one second before new year UTC
Version is the API version like 2013-09-01
additional parameters may be needed for your call, depending on the value of Action
Please note:
The NEWLINE character is just "\n", not "\r\n"
The name of the host should not include "https://" or "http://"
The Signature parameter is necessary for the actual call later (see step 3), but is not part of the string_to_sign.
Your string_to_sign should now look somewhat like this:
POST
mws.amazonservices.com
/Orders/2013-09-01
AWSAccessKeyId=12345678901234567890&Action=ListOrders&CreatedAfter .... &Version=2013-09-01
Step 2, signing that string
Calculate a SHA256 hash of above string using the 40-character Secret Key
Encode this hash using Base64
In Pseudocode: signature = Base64encode( SHA256( string_to_sign, secret_key ))
Step 3, send the call
Send a HTTPS POST request, using the full alphabetical list of parameters, now including above signature as Signature somewhere in the middle, because you need to keep ascending alphabetical order.
https://mws.amazonservices.com/Orders/2013-09-01?AWSAccessKeyId....Version=2013-09-01
Step 4, processing the result
You should be getting two things back: a response header and a XML document. Be sure to evaluate the HTTP status in the header as well as all contents of the XML document. Some error messages are hidden deeply in XML while HTTP returns "200 OK".
Step 5, Advanced Stuff
If you use calls that require you to send a document, like SendFeed, you need to do the following additional steps:
Calculate the MD5 hash of your document
Encode this hash using Base64
In Pseudocode: contentmd5= Base64encode( MD5( document ))
Add Content-Type: text/xml (or whatever fits your document) as HTTP header
Add Content-MD5: plus the base64 encoded hash as HTTP header
This code was a great help for building a similar application. I corrected some small issues to bring it up to work:
before signing the ISODate need to be worked out to replace the ":" chars
var todayTime = ISODateString(today);
var todayISO = todayTime;
var todayTime_ = todayTime.replace(":", "%3A");
todayTime = todayTime_.replace(":","%3A");
The same for the calculated signature (quick & dirty solution, replace only 3 appearences and need to updated for more chars)
Logger.log(unsignedURL);
var tmpsignature = calculatedSignature(unsignedURL);
var orsignature = tmpsignature;
// encode special chars
tmpsignature = encodeURIComponent(orsignature);
}
I added a header and dropped the form, put all parameters in the url
var header = {
"x-amazon-user-agent": "GoogleSheets/1.0 (Language=Javascript)",
"Content-Type": "application/x-www-form-urlencoded"
// "Content-Type": "text/xml"
};
var options = {
"method" : "post",
"muteHttpExceptions" : true,
// "payload" : formData,
"header":header
};
And changed the call to url encoded (Form was not working, do not know why)
var url = 'https:mws-eu.amazonservices.com/Orders/2013-09-01?'+
'AWSAccessKeyId=<your stuff>'+
'&Action=GetOrder'+
'&SellerId=<your stuff>+
'&MWSAuthToken=<your token>'+
'&SignatureVersion=2'+
'&Timestamp='+todayTime'+ // remember to replace the ":" thru hex
'&Version=2013-09-01'+
'&Signature='+ tmpsignature+
'&SignatureMethod=HmacSHA256'+
'&AmazonOrderId.Id.1='+<your order;
parsed the response:
var result = UrlFetchApp.fetch(url, options);
//writeDataToXML(result);
Logger.log(result);
var xml = result.getContentText();
var document = XmlService.parse(xml);
This worked! :-)
I checked the signature also with
https://mws-eu.amazonservices.com/scratchpad/index.html
i am attempting to combine php-gzdeflate and pako. to compress the string i am using:
const compressed = ' <?php echo base64_encode(gzdeflate('Compress me')); ?> ' ;
// compressed now contains: c87PLShKLS5WyE0FAA==
but i cannot seem to read this string back using pako. i have tried the following:
var enc = new TextEncoder("utf-8");
pako.ungzip(enc.encode(compressed) );
i get this message back: uncaught incorrect header check
is there a simple way to compress using generic-php and inflate using pako?
so far i have tried adding various gzdeflate "levels" from one to nine, but none of them appear to make any difference. and at this point, i am just guessing.
and we would rather not install any special extension to php if possible
thank you very much.
Update to #edwardsmarkf's answer you can solve this without the atos function now. Most newer browsers have the TextDecoder api. You can use it like so:
const decoder = new TextDecoder();
const result = decoder.decode(pako.ungzip(atob(compressedBase64Data)));
I couldn't get the answers here to work, so I did some research.
As PleaseStand pointed out here, the problem is that PHP uses UTF-8 strings, while JS uses UTF-16 strings. Hence, the binary string to base64 string encoding will differ.
The solution I used is to force JS to interpret the data as UTF-8. This is straightforward, as pako accepts and returns Uint8Arrays, which are essentially UTF-8 strings.:
Compress in JS, Decompress in PHP:
//JS
const pako = require('pako');
const compress = str => Buffer.from(pako.deflateRaw(str)).toString('base64');
console.log(compress('asdfasdfasdfasdf')); //SyxOSUtEwgA=
//PHP
function decompress($str) { return gzinflate(base64_decode($str)); }
echo decompress('SyxOSUtEwgA='); //asdfasdfasdfasdf
Compress in PHP, Decompress in JS:
//PHP
function compress($str) { return base64_encode(gzdeflate($str, 9)); }
echo compress('asdfasdfasdf'); //SyxOSUuEYgA=
//JS
const pako = require('pako');
const decompress = str => pako.inflateRaw(Buffer.from(str, 'base64'), {to: 'string'});
console.log(decompress('SyxOSUuEYgA=')); //asdfasdfasdfs
Note: Buffer instances are also Uint8Array instances, hence we don't need to convert the Buffer to a Uint8Array before giving it to pako.
These functions are also compatible within the languages:
//JS
console.log(decompress(compress('asdfasdfasdfasdf'))); //asdfasdfasdfasdf
//PHP
echo decompress(compress('asdfasdfasdfasdf')); //asdfasdfasdfasdf
For JS, this works out of the box in NodeJs. In a browser environment, you will need a polyfil for Buffer.
For PHP, remember to install the Zlib extension.
I'm not familiar with php, so I kinda struggled with this problem, so I thought to post a minimal working solution in php:
$response = gzdeflate('My data', 9, ZLIB_ENCODING_DEFLATE);
header('Content-Encoding: deflate');
echo $response;
No need to use pako after this, the data will be decompressed by the browser.
Example if you're requesting json formatted data:
$.ajax({
type: 'GET',
url: 'http://target.com',
dataType: "json",
contentType: "application/json; charset=utf-8",
headers : {'Accept-Encoding': 'deflate '},
})
.done(function(res) {
console.log(res)
})
.fail(function(xhr, textStatus, errorThrown) {
});
This appears to work(below)
Steps involved:
server side (php):
1) gzdeflate using ZLIB_ENCODING_DEFLATE option
2) base64_encode
client side:(jScript)
1) atob
2) pako.ungzip
3) atos function
<script src='//cdnjs.cloudflare.com/ajax/libs/pako/1.0.5/pako_deflate.js' type='text/javascript'></script>
<script type='text/javascript'>
const compressedDEFLATE = '<?php echo base64_encode(gzdeflate('Compress me', 6, ZLIB_ENCODING_DEFLATE )); ?>' ;
function atos(arr) {
for (var i=0, l=arr.length, s='', c; c = arr[i++];)
s += String.fromCharCode(
c > 0xdf && c < 0xf0 && i < l-1
? (c & 0xf) << 12 | (arr[i++] & 0x3f) << 6 | arr[i++] & 0x3f
: c > 0x7f && i < l
? (c & 0x1f) << 6 | arr[i++] & 0x3f
: c
);
return s
}
alert ( atos(pako.ungzip( atob(compressedDEFLATE) ) ) );
</script>
I am passing two JSON objects from jQuery - ajax call to servlet using JSON Stringify. But I am getting null. If I pass one Object I am getting expected data but I'm not able to receive two objects. Please help me to find my mistake.
$.ajax({
url : 'insertserv1',
type: 'POST',
dataType: 'json',
data: JSON.stringify({"test1" :masterdata,"test2" :InspTableArray}),
contentType: 'application/json',
mimeType: 'application/json',
success : function(data) {
alert('Hi');
}
});
BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
if (br != null) {
json = br.readLine();
}
System.out.println(json); // getting expected data as {"test1":{"grn":"55555","pono":"888888","row":1},"test2":["Type/,"As ","ok","ok","ok","ok","ok"]}
try {
JSONObject rawdata = new JSONObject(json);
JSONObject datat1 = rawdata.getJSONObject("test1");
JSONObject datat2 = rawdata.getJSONObject("test2");
System.out.println(datat1); // return nulls
System.out.println(datat2); // return nulls
The JSON that is being sent in the InspTableArray is invalid so when you try and parse it in Java it breaks:
{"test1":{"grn":"55555","pono":"888888","row":1},"test2":["Type/,"As ","ok","ok","ok","ok","ok"]}
// Problem is this character here --------------------------^
// which breaks the JSON Array of strings
// The value should be "Type" instead of "Type/
// and is likely causing a SyntaxError: Unexpected token A in JSON at position 66
test2 seems to be an array of strings, apart from the first element which isn't a String and causes the rest of the Array to break and should be:
"test2":["Type","As ","ok","ok","ok","ok","ok"]
// ^------ forward slash replaced with closing double-quotation mark
What I needed:
We have value in the response.d that is comma deliminated value. Now I want to export the data of response.d to .csv file.
I have written this function to perform this. I have received the data in response.d but not exporting to the .csv file, so give the solution for this problem to export data in .csv file.
function BindSubDivCSV(){
$.ajax({
type: "POST",
url: "../../WebCodeService.asmx / ShowTrackSectorDepartureList",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
alert(response.d);//export to csv function needed here
},
error: function (data) {}
});
return false;
}
In case you have no control over how the server-side works, here is a client-side solution that I have offered in another SO question, pending for that OP's acceptance: Export to CSV using jQuery and html
There are certain restrictions or limitations you will have to consider, as I have mentioned in my answer over there, which has more details.
This is the same demo I have offered:
http://jsfiddle.net/terryyounghk/KPEGU/
And to give you a rough idea of what the script looks like.
What you need to change is how you iterate your data (in the other question's case it was table cells) to construct a valid CSV string. This should be trivial.
$(document).ready(function () {
function exportTableToCSV($table, filename) {
var $rows = $table.find('tr:has(td)'),
// Temporary delimiter characters unlikely to be typed by keyboard
// This is to avoid accidentally splitting the actual contents
tmpColDelim = String.fromCharCode(11), // vertical tab character
tmpRowDelim = String.fromCharCode(0), // null character
// actual delimiter characters for CSV format
colDelim = '","',
rowDelim = '"\r\n"',
// Grab text from table into CSV formatted string
csv = '"' + $rows.map(function (i, row) {
var $row = $(row),
$cols = $row.find('td');
return $cols.map(function (j, col) {
var $col = $(col),
text = $col.text();
return text.replace('"', '""'); // escape double quotes
}).get().join(tmpColDelim);
}).get().join(tmpRowDelim)
.split(tmpRowDelim).join(rowDelim)
.split(tmpColDelim).join(colDelim) + '"',
// Data URI
csvData = 'data:application/csv;charset=utf-8,' + encodeURIComponent(csv);
$(this)
.attr({
'download': filename,
'href': csvData,
'target': '_blank'
});
}
// This must be a hyperlink
$(".export").on('click', function (event) {
// CSV
exportTableToCSV.apply(this, [$('#dvData>table'), 'export.csv']);
// IF CSV, don't do event.preventDefault() or return false
// We actually need this to be a typical hyperlink
});
});
Using the code above (from Terry Young) I found that in Opera it would refuse to give the file a name (simply calling it "download") and would not always work reliably.
To get it to work I had to create a binary blob:
var filename = 'file.csv';
var outputCSV = 'entry1,entry2,entry3';
var blobby = new Blob([outputCSV], {type: 'text/plain'});
$(exportLink).attr({
'download' : filename,
'href': window.URL.createObjectURL(blobby),
'target': '_blank'
});
exportLink.click();
Also note that creating the "exportLink" variable on the fly would not work with Firefox so I had to have this in my HTML file:
<div>
<a id="exportLink"></a>
</div>
Using the above I have successfully tested this using Windows 7 64bit and Opera (v22), Firefox (v29.0.1), and Chrome (v35.0.1916.153 m).
To enable similar functionality (albeit in a far less elegant manner) on Internet Explorer I had to use Downloadify.