J
J
JackShcherbakov2019-03-03 14:21:42
PHP
JackShcherbakov, 2019-03-03 14:21:42

net::ERR_ABORTED 413 (Request Entity Too Large) error - how to fix?

Hello!
I am writing an application that takes a photo every 8 seconds and sends it to the server, where it is compressed and saved. The site has a canvas that copies a "freeze frame" from the video tag once per second. Then the image is copied from the canvas to the src of the img element. src looks like this:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABQAAAALQCAYAAADPfd1WAAAgAElEQVR4Xqy9a49sS3IdtuvV5w4tGP5xIi2Tog3JEg2LlP1FgH+2ZQOcuafrZaxXRGR2n+EIcA0G53Z3Ve29MyPjsWJFxOl//D//r/f7/T7Ox+N4vV/H6fjn4/16H5fz/TidTsf79fuB1/l8Pk7n83E5Lvw5r/fzx3G7XY/T+zge98fxev7u976O1/N5nI7Hge+/nE7H+Xw53q/z8XrhOpfjer0e9/OZX/U83sf79dK1LpfjdMJ73+M6z+N8Oh+Xjyu/7+fjru/57YM/P9/v4/3W5/Hzceh7j/EdfB7//n0+HZfL5Xi9n7zP8/vM616Ok+73dfD5L++D93E+Xvz5enryX/z/fDodz9NP/Xx+8HKP40/8/Ot84ffdnzf9fPrv [И еще оооочень много символов]

That is, the base64 code is written directly to src. This code is sent as a POST request to the server.
The problem is that if this same code is more than a megabyte, then an error occurs due to the request being too large.
On the local machine, I tested without any errors, everything worked fine. Everything worked perfectly until I uploaded the files to the hosting.
On the hosting, he simply changed the resolution of the video, thereby reducing the size of the base64 code by several times, and he successfully sent it to the server.
But I want exactly 1280 by 640 at least, if you make the height and width of the video (that is, the resolution) half as small, the error will disappear, but this option does not suit me.
The server returns an HTTP 413 Request Entity Too Large error. I tried to write these lines in php server:
ini_set('upload_max_filesize', '500M');
ini_set('post_max_size', '500M');
header('Access-Control-Allow-Origin: *'); //JavaScript отправляет фото с другого домена

Didn't help at all
The code in the spoiler:
spoiler
Давайте пробежимся по коду:
Не думаю, что это особо поможет в решении, но мало ли.
JavaScript
делает снимок раз в 8 секунд и отправляет на сервер в виде кода base64
//Делаем снимки раз в 8 сек:

var user_id = 1;

var hidden_div = document.createElement("DIV");

hidden_div.innerHTML = '<video class="camera_stream"></video>\
  <canvas width="1280" height="720"></canvas>\
  <img class="photo">';

document.body.append(hidden_div);

hidden_div.hidden = true;


var constraints = { audio: false, video: { width: 1280, height: 720 } }; 
  
  // Older browsers might not implement mediaDevices at all, so we set an empty object first
if (navigator.mediaDevices === undefined) {
  navigator.mediaDevices = {};
}

// Some browsers partially implement mediaDevices. We can't just assign an object
// with getUserMedia as it would overwrite existing properties.
// Here, we will just add the getUserMedia property if it's missing.
if (navigator.mediaDevices.getUserMedia === undefined) {
  navigator.mediaDevices.getUserMedia = function(constraints) {

    // First get ahold of the legacy getUserMedia, if present
    var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

    // Some browsers just don't implement it - return a rejected promise with an error
    // to keep a consistent interface
    if (!getUserMedia) {
      return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
    }

    // Otherwise, wrap the call to the old navigator.getUserMedia with a Promise
    return new Promise(function(resolve, reject) {
      getUserMedia.call(navigator, constraints, resolve, reject);
    });
  }
}

navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
  var video = document.querySelector('video');
  // Older browsers may not have srcObject
  if ("srcObject" in video) {
    video.srcObject = stream;
  } else {
    // Avoid using this in new browsers, as it is going away.
    video.src = window.URL.createObjectURL(stream);
  }
  video.onloadedmetadata = function(e) {
    video.play();
  };
})
.catch(function(err) {
  console.log(err.name + ": " + err.message);
});

function takeSnapshot(){

    var hidden_canvas = document.querySelector('canvas'),
        video = document.querySelector('video.camera_stream'),
        image = document.querySelector('img.photo'),

        // Получаем размер видео элемента.
        width = video.videoWidth,
        height = video.videoHeight,

        // Объект для работы с canvas.
        context = hidden_canvas.getContext('2d');


    // Установка размеров canvas идентичных с video.
    hidden_canvas.width = width;
    hidden_canvas.height = height;

    // Отрисовка текущего кадра с video в canvas.
    context.drawImage(video, 0, 0, width, height);

    // Преобразование кадра в изображение dataURL.
    var imageDataURL = hidden_canvas.toDataURL('image/png');

    // Помещение изображения в элемент img.
    image.setAttribute('src', imageDataURL);

    var form_data = new FormData();

    form_data.append("user_id", user_id);
    form_data.append("base64", imageDataURL);


    // if(imageDataURL.length<200){
    //   takeSnapshot();
    //   console.log("imageDataURL.length<200 - вызываем takeSnapshot");
    //   console.log("imageDataURL.length<200 - вызываем takeSnapshot");
    //   console.log("imageDataURL.length<200 - вызываем takeSnapshot");
    //   console.log("imageDataURL.length<200 - вызываем takeSnapshot");
    //   console.log("imageDataURL.length<200 - вызываем takeSnapshot");
    //   console.log("imageDataURL.length<200 - вызываем takeSnapshot");
    //   console.log("imageDataURL.length<200 - вызываем takeSnapshot");
    //   console.log("imageDataURL.length<200 - вызываем takeSnapshot");
    //   return false;
    // }

    var xhr = new XMLHttpRequest();
    xhr.open("POST", "xxxx.php");
    xhr.onload = function(e) {


      console.log(this.responseText);

    }

    xhr.send(form_data)


}

setInterval(function(){
  takeSnapshot();
}, 8000);

PHP
принимает картинку, которую отправил JavaScript в формате base64, сжимает ее и сохраняет в файл:
<?php 

header('Access-Control-Allow-Origin: *');


if(isset($_POST["base64"]) && isset($_POST["user_id"]) ){

$base64 = $_POST["base64"];
$user_id = $_POST["user_id"];

    // file_put_contents("bases.txt",  file_get_contents("bases.txt") . "\n" . $base64);


// $number = 64;

//   function generate_image_name($number)
//   {
//     $arr = array('1','2','3','4','5','6',
//                  '7','8','9','0');
//     // Генерируем пароль
//     $pass = "";
//     for($i = 0; $i < $number; $i++)
//     {
//       // Вычисляем случайный индекс массива
//       $index = rand(0, count($arr) - 1);
//       $pass .= $arr[$index];
//     }
//     return $pass;
//   }
//   
 function resize_photo($src, $type, $quality){

        switch($type){
            case 'image/jpeg': $source = imagecreatefromjpeg($src); break; //Создаём изображения по
            case 'image/png': $source = imagecreatefrompng($src); break;  //образцу загруженного  
            case 'image/gif': $source = imagecreatefromgif($src); break; //исходя из его формата
            default : return false;
        }
        imagejpeg($source, $src, $quality); //Сохраняем созданное изображение по указанному пути в формате jpg
        imagedestroy($source);//Чистим память
        echo "Фото было сжато успешно!\n";
        return true;
}

function base64_to_jpeg($base64_string, $output_file) {
    // open the output file for writing
    $ifp = fopen( $output_file, 'wb' ); 

    // split the string on commas
    // $data[ 0 ] == "data:image/png;base64"
    // $data[ 1 ] == <actual base64 string>
    $data = explode( ',', $base64_string );

    // we could add validation here with ensuring count( $data ) > 1
    fwrite( $ifp, base64_decode( $data[ 1 ] ) );

    // clean up the file resource
    fclose( $ifp ); 

    return $output_file; 
}

$src = "photos/" . date("Y-m-d h-i-s") . " - ". $user_id  .".jpeg";

base64_to_jpeg($base64, $src);

$quality = 60;

resize_photo($src,'image/png',  $quality);

echo "Фотография была успешно сохранена";
exit;
}
echo "Что то пошло не так";
?>

Thanks in advance to everyone who helps!

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Andrey Gorbatsevich, 2019-03-03
@Nuark

And if you try like this:
In JS:

...
let data = {
    user_id: "UID",
    base64: "b64"
};
let request= new XMLHttpRequest();
request.open("POST", "xxxxx.php", true);
request.setRequestHeader("Content-type", "application/json");
request.send(JSON.stringify(data));
...

In PHP:
$str_json = file_get_contents('php://input');
$jdom = json_decode($str_json);

if(!array_key_exists("base64", $jdom) || !array_key_exists("user_id", $jdom))
    die("NO BASE64/UID");

$base64 = $jdom["base64"];
$user_id = $jdom["user_id"];
...

V
Vasily Varyukhin, 2019-03-03
@Hocopor

Apache.htaccess
ini_set defines a config for php. Your web server is returning an error.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question