Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I send a Blob of type octet/stream to server using AJAX?

I have unsuccessfully been trying to send a Blob file (which is an .OBJ file type) to the server using AJAX. I want to be able to do this without using an input file field. I am making an online avatar creator, so the Blob file to be sent to the server is generated from the character that is initially imported into my Three.js scene. I have been able to send a Blob file that contains a String to the server and save this to a specified folder (which I am aiming to do with the Blob .OBJ file). I have tried converting the Blob to Base64 before sending it in a POST request, but this did not work. The size of the file that I am trying to send is 3MB.

Here is my JavaScript code for creating the Blob file and sending it to my PHP script on the server using AJAX.

//Create OBJ
var exporter = new THREE.OBJExporter();
var result = exporter.parse(child);

//Generate file to send to server
var formData = new FormData();
var characterBlob = new Blob([result], {type: "octet/stream"});

var reader = new FileReader();
reader.readAsDataURL(characterBlob);
reader.onloadend = function() {
formData.append('file', reader.result);

    $.ajax({
    url: "ExecuteMaya.php", // Url to which the request is send
    type: "POST",             // Type of request to be send, called as method
    data: formData, // Data sent to server, a set of key/value pairs (i.e. form fields and values)
    processData:false,        // To send DOMDocument or non processed data file it is set to false
    contentType: false,       // The content type used when sending data to the server
    }).done(function(data) {
        console.log(data);
    });
}

Here is my PHP script for handling the sent file.

<?php

$sourcePath = $_FILES['file']['tmp_name'];       // Storing source path of the file in a variable
$targetPath = "upload/".$_FILES['file']['name']; // Target path where file is to be stored
move_uploaded_file($sourcePath,$targetPath) ;    // Moving Uploaded file
echo "<span id='success'>Image Uploaded Successfully...!!</span><br/>";
echo "<br/><b>File Name:</b> " . $_FILES["file"]["name"] . "<br>";
echo "<b>Type:</b> " . $_FILES["file"]["type"] . "<br>";
echo "<b>Size:</b> " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
echo "<b>Temp file:</b> " . $_FILES["file"]["tmp_name"] . "<br>";

?>

Any help would be much appreciated!

UPDATE 1: The var result = exporter.parse(child); is a String and whenever I print this variable to the console it takes a few minutes to load. Would the size of this String be a possible issue with trying to send it to the server?

UPDATE 2: This gets printed to the console after the PHP script has been executed, which makes me think that either nothing is being sent over to the server or the sent data is not being handled correctly by the PHP script.

Image Uploaded Successfully...!!

File Name:
Type:
Size: 0 kB
Temp file:

UPDATE 3: Here is a link to the file that I am trying to send. http://www.filehosting.org/file/details/578744/CleanFemaleOBJ.obj

You can view this file in TextEdit/NotePad to view the String that I want to send. It is pretty much a text file with the .obj extension to convert it to that format so it can be opened in Maya.

UPDATE 4: I have now altered my JavaScript code so that the Blob is appended to the FormData and not the result of reader.readAsDataURL(characterBlob).

//Create OBJ
var exporter = new THREE.OBJExporter();
var result = exporter.parse(child);

//Generate file to send to server
var formData = new FormData();
var characterBlob = new Blob([result], {type: "octet/stream"});
formData.append('file', result);                            

    $.ajax({
    url: "ExecuteMaya.php", // Url to which the request is send
    type: "POST", // Type of request to be send, called as method
    data: formData, // Data sent to server, a set of key/value pairs (i.e. form fields and values)
    processData: false, // To send DOMDocument or non processed data file it is set to false
    }).done(function(data) {
        console.log(data);
    });
like image 469
skelto Avatar asked Jun 17 '16 09:06

skelto


1 Answers

Using the following code, I was able to upload the .obj file.

I had to increase my maximum upload size for it to work.

You may also think of increasing your maximum execution time as commented below, but I didn't have to.

For simplicity, I put everything in one file called form.php.

form.php

<?php
// good idea to turn on errors during development
error_reporting(E_ALL);
ini_set('display_errors', 1);

// ini_set('max_execution_time', 300);

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    echo "<br/><b>File Name:</b> " . $_FILES["file"]["name"] . "<br>";
    echo "<b>Type:</b> " . $_FILES["file"]["type"] . "<br>";
    echo "<b>Size:</b> " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
    echo "<b>Temp file:</b> " . $_FILES["file"]["tmp_name"] . "<br>";
    echo "<b>Error:</b> " . $_FILES["file"]["error"] . "<br>";

    $sourcePath = $_FILES['file']['tmp_name'];          // Storing source path of the file in a variable
    $targetPath = "uploads/" . $_FILES['file']['name'];    // Target path where file is to be stored
    if (move_uploaded_file($sourcePath, $targetPath)) { // Moving Uploaded file
        echo "<span id='success'>Image Uploaded Successfully...!!</span><br/>";
    } else {
        echo "<span id='success'>Image was not Uploaded</span><br/>";
    }
    exit;
}
?>

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
</head>
<body>
    <form action="form.php" method="post" enctype="multipart/form-data">
        <label>File</label>
        <input type="file" name="file">
        <input type="submit" value="Upload"> 
    </form>
    <div></div>
</body>
<script>
$(function () {
    $('form').on('submit', function (e) {
        e.preventDefault();
        // logic
        $.ajax({
            url: this.action,
            type: this.method,
            data: new FormData(this), // important
            processData: false, // important
            contentType: false, // important
            success: function (res) {
                $('div').html(res);
            }
        });
    });
});
</script>
</html>

So, first test to see if you can upload the .obj file using the code above.

As you are testing it out, have your browser's developer tool open. Monitor your Network/XHR tab [Chrome, Firefox] to see the request that gets made when you click Upload.

If it works, try using the same logic in your original code.

var formData = new FormData();
formData.append('file', result);   

$.ajax({
    url: "ExecuteMaya.php",
    type: "post",
    data: formData, // important
    processData: false, // important
    contentType: false, // important!
    success: function (res) {
        console.log(res);
    }
});

Again, monitor the request made in your Network/XHR tab and look at what is being sent.

like image 58
Mikey Avatar answered Oct 14 '22 18:10

Mikey