Сгенерировать png-файл с php из dataURI, отправленного через ajax

У меня есть svg-файл, который генерирует dataURI-png, и это отлично работает. И я хочу, чтобы dataURI сохранялся как изображение, поэтому я пытаюсь отправить dataURI через ajax на другой сервер, который может выполнять PHP. Но я не могу заставить его работать.

Это код для генерации dataURI (который работает)

var mySVG = document.querySelector('svg'), // Inline SVG element tgtImage = document.querySelector('.tgtImage'); // Where to draw the result can = document.createElement('canvas'), // Not shown on page ctx = can.getContext('2d'), loader = new Image; // Not shown on page console.log(mySVG); loader.width = can.width = tgtImage.width; loader.height = can.height = tgtImage.height; loader.onload = function(){ ctx.drawImage( loader, 0, 0, loader.width, loader.height ); tgtImage.src = can.toDataURL("image/png"); }; 

Это ajax-код для отправки на внешний php-сервер:

 $.ajax({ type: "POST", data: {id:'testID',datauri: can.toDataURL("image/png")}, crossDomain: true, //dataType: "jsonp", url: "https://urltoscript.php", success: function (data) { console.log(data); }, error: function (data) { console.log(data); } }); 

PHP-код для генерации png

 $dataUrl = $_REQUEST['datauri']; $id = $_REQUEST['id']; list($meta, $content) = explode(',', $dataUrl); $content = base64_decode($content); file_put_contents('./tmp-png/'.$id.'.png', $content); 

Генерация PNG работает при ручной вставке dataURI. Но он не работает с вышеописанной функцией ajax.

Спасибо!

Вы можете использовать canvas.toBlob() , отправить изображение на php в виде Blob , использовать php://input для чтения Blob на php , см. Beyond $ _POST, $ _GET и $ _FILE: Работа с Blob в JavaScript и PHP

Javascript

 if (!HTMLCanvasElement.prototype.toBlob) { Object.defineProperty(HTMLCanvasElement.prototype, "toBlob", { value: function (callback, type, quality) { var binStr = atob( this.toDataURL(type, quality).split(",")[1] ), len = binStr.length, arr = new Uint8Array(len); for (var i=0; i<len; i++ ) { arr[i] = binStr.charCodeAt(i); } callback( new Blob( [arr], {type: type || "image/png"} ) ); } }); } can.toBlob(function(blob) { var request = new XMLHttpRequest(); // to receive `echo`ed file from `php` as `Blob` // request.responseType = "blob"; request.open("POST", "readBlobInput.php", true); request.setRequestHeader("x-file-name", "filename"); request.onload = function() { // `this.response` : `Blob` `echo`ed from `php` // console.log(this.response) console.log(this.responseText); } request.send(blob) }); 

readBlobInput.php

 <?php // the Blob will be in the input stream, so we use php://input $input = file_get_contents("php://input"); // choose a filename, use request header $tmpFilename = $_SERVER["HTTP_X_FILE_NAME"]; // http://stackoverflow.com/q/541430/ $folder = __DIR__ . "/tmp-png"; // http://stackoverflow.com/q/17213403/ is_dir($folder) || @mkdir($folder) || die("Can't Create folder"); // put contents of file in folder file_put_contents($folder . "/" . $tmpFilename, $input); // get MIME type of file $mime = mime_content_type($folder . "/" . $tmpFilename); $type = explode("/", $mime); // set MIME type at file $filename = $tmpFilename . "." . $type[1]; // rename file including MIME type rename($folder . "/" . $tmpFilename, $folder . "/" . $filename); // to echo file // header("Content-Type: " . $type); // echo file_get_contents($newName); echo $filename . " created"; ?> 
 $dataUrl = $_REQUEST['datauri']; $id = $_REQUEST['id']; list($meta, $content) = explode(',', $dataUrl); $content = str_replace(".", "", $content); // some android browsers will return a data64 that may not be accurate without this without this. $content = base64_decode($content); $image = imagecreatefromstring($content); imagepng($image, './tmp-png/'.$id.'.png', 90); // Third parameter is optional. Just placed it incase you want to save storage space...