How to use flatbuffer generated data in browser? - javascript

I'm trying to use flatbuffer in one of my web application. I've already stored those buffer data in one file (buffer_content.txt) by using following php code.
// ...Code to store to disk or send over a network goes here...
$file = 'buffer_content.txt';
$output = serialize($builder->dataBuffer());
$fp = fopen($file, "w");
fwrite($fp, $output);
fclose($fp);
Through ajax I can get the buffer data from the server. Now I need to extract the original data from that buffer in JavaScript. But, I can't able to fig out how to do that.
Any idea, how to do this ?

After referring Aardappel answer I did following changes in my code to solve this problem.
Create buffer file
$file = 'buffer_content.bin';
$output = $builder->dataBuffer();
$fp = fopen($file, "wb");
fwrite($fp, $output);
fclose($fp);
Code for getting buffer content from file & response back to ajax call
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
// change these to whatever is appropriate in your code
$my_place = "/path/to/the/file/"; // directory of your file
$my_file = "item.bin"; // your file
//$my_path = $my_place.$my_file;
$my_path = $my_file;
header("Pragma: public");
header("Expires: 0");
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: pre-check=0, post-check=0, max-age=0', false);
header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
$browser = $_SERVER['HTTP_USER_AGENT'];
if(preg_match('/MSIE 5.5/', $browser) || preg_match('/MSIE 6.0/', $browser))
{
header('Pragma: private');
// the c in control is lowercase, didnt work for me with uppercase
header('Cache-control: private, must-revalidate');
// MUST be a number for IE
header("Content-Length: ".filesize($my_path));
header('Content-Type: application/x-download');
header('Content-Disposition: attachment; filename="'.$my_file.'"');
}
else
{
header("Content-Length: ".(string)(filesize($my_path)));
header('Content-Type: application/x-download');
header('Content-Disposition: attachment; filename="'.$my_file.'"');
}
header('Content-Transfer-Encoding: binary');
if ($file = fopen($my_path, 'rb'))
{
while(!feof($file) and (connection_status()==0))
{
print(fread($file, filesize($my_path)));
flush();
}
fclose($file);
}
?>
Code for Parsing binary data at client side
var xhr = new XMLHttpRequest();
xhr.open('GET', 'getBufferData.php', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
// response is unsigned 8 bit integer
var responseArray = new Uint8Array(this.response);
var buf = new flatbuffers.ByteBuffer(responseArray);
var monster = MyGame.Sample.Monster.getRootAsMonster(buf);
var hp = monster.hp();
var pos = monster.pos();
console.log("hp : "+hp);
console.log("pos : "+pos);
};
xhr.send();

You don't want to use serialize. the dataBuffer already contains serialized data, check out what it says here:
https://google.github.io/flatbuffers/flatbuffers_guide_tutorial.html
$buf = $builder->dataBuffer(); // Of type Google\FlatBuffers\ByteBuffer
// The data in this ByteBuffer does NOT start at 0, but at buf->getPosition().
// The end of the data is marked by buf->capacity(), so the size is
// buf->capacity() - buf->getPosition().
Make sure you write the file in binary mode (pass "wb" to fopen). Also don't call it .txt since it isn't a text format :)
Then in JS, you read in the file (again, in binary mode, not text), make sure it ends up in a Uint8Array, then follow the code here: https://google.github.io/flatbuffers/flatbuffers_guide_use_javascript.html

Related

PHP readfile download from ajax request showing binary

I am trying to get my php script to download an image which the name of is being sent in from an ajax function in my javascript, and I think I'm using all the right headers and then I'm using readfile() to download the image, and when I preview the php when it runs with the chrome developer tools (ctrl+shift+i-> network -> XHR -> preview) all I get is a bunch of gibberish binary and my image doesn't download. Does anyone know why this is happening/how to fix it?
Here's my ajax which is just in a function that runs when a "download" button is clicked
$.ajax({
type: "POST",
url: 'requestAJAX.php',
data: {request: request, download: imageName},
success: function(){
console.log("Request Completed: " + request);
} // success
});
and here's my "requestAJAX.php"
<?php
switch ($_POST["request"]) {
case "download":
// Get parameters
$file = $_POST["download"];
$filepath = "UploadedImages/" . $file;
if(file_exists($filepath)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$file.'"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($filepath));
ob_clean();
flush();
// download
readfile($filepath);
exit;
} // if
break;
default:
echo "No request was made";
}
?>
and this is what I'm getting when I preview (not sure how it will help)
ÿØÿàJFIFHHÿâ#ICC_PROFILE0appl mntrRGB XYZ ÙacspAPPLapplöÖÓ-appldscmòdescüogXYZlwtptrXYZbXYZ¨rTRC¼cprtÌ8chad,gTRC¼bTRC¼mlucenUS&~esES&daDK.êdeDE,¨fiFI(ÜfrFU(*itIT(VnlNL(nbNO&ptBR&svSE&jaJPRkoKR#zhTWlzhCNÔruRU"¤plPL,ÆYleinen RGB-profiiliGenerisk RGB-profilProfil Générique RVBN, RGB 0×0í0Õ0¡0¤0ëu( RGB r_icÏðPerfil RGB GenéricoAllgemeines RGB-Profilfn RGB cÏðeNöGenerel RGB-beskrivelseAlgemeen RGB-profielÇ|¼ RGB Õ¸\ÓÇ|Profilo RGB GenericoGeneric RGB Profile1I89 ?#>D8;L RGBUniwersalny profil RGBdescGeneric RGB ProfileGeneric RGB ProfileXYZ Zu¬s4XYZ óRÏXYZ tM=îÐXYZ (¸6curvÍtextCopyright 2007 Apple Inc., all rights reserved.sf32BÞÿÿó&ýÿÿû¢ÿÿý£ÜÀlÿáExifMM*JR(iZHH é ¡ÿÛC
Thanks in advance for any assistance!

How to play audio file using ajax when it return to php variable

I am trying to play music dynamically from ajax response data but the problem is how to play audio file when it return to php variable?
I am using mediaelement.js pluging for audio player.
JAVASCRIPT
var player = new MediaElementPlayer('audio-player', {
//options
});
$.ajax({
url: '../play?song=songs_id',
type: "get",
success:function(data){
player.pause();
player.setSrc(data);
player.load();
player.play();
}
});
PHP
$song_id = 'folder/'.$_GET['song'];
// get the file request, throw error if nothing supplied
// hide notices
#ini_set('error_reporting', E_ALL & ~ E_NOTICE);
//- turn off compression on the server
#apache_setenv('no-gzip', 1);
#ini_set('zlib.output_compression', 'Off');
// sanitize the file request, keep just the name and extension
// also, replaces the file location with a preset one ('./myfiles/' in this example)
$file = $song_id;
$path_parts = pathinfo($file);
$file_name = $path_parts['basename'];
$file_ext = $path_parts['extension'];
$file_path = $song_id;
// allow a file to be streamed instead of sent as an attachment
$is_attachment = isset($_REQUEST['stream']) ? false : true;
// make sure the file exists
if (is_file($file_path))
{
$file_size = filesize($file_path);
$file = #fopen($file_path,"rb");
if ($file)
{
// set the headers, prevent caching
header("Pragma: public");
header("Expires: -1");
header("Cache-Control: public, must-revalidate, post-check=0, pre-check=0");
header("Content-Disposition: attachment; filename=\"$file_name\"");
// set appropriate headers for attachment or streamed file
if ($is_attachment) {
header("Content-Disposition: attachment; filename=\"$file_name\"");
}
else {
header('Content-Disposition: inline;');
header('Content-Transfer-Encoding: binary');
}
// set the mime type based on extension, add yours if needed.
$ctype_default = "application/octet-stream";
$content_types = array(
"exe" => "application/octet-stream",
"zip" => "application/zip",
"mp3" => "audio/mpeg",
"mpg" => "video/mpeg",
"avi" => "video/x-msvideo",
);
$ctype = isset($content_types[$file_ext]) ? $content_types[$file_ext] : $ctype_default;
header("Content-Type: " . $ctype);
//check if http_range is sent by browser (or download manager)
if(isset($_SERVER['HTTP_RANGE']))
{
list($size_unit, $range_orig) = explode('=', $_SERVER['HTTP_RANGE'], 2);
if ($size_unit == 'bytes')
{
//multiple ranges could be specified at the same time, but for simplicity only serve the first range
//http://tools.ietf.org/id/draft-ietf-http-range-retrieval-00.txt
list($range, $extra_ranges) = explode(',', $range_orig, 2);
}
else
{
$range = '';
header('HTTP/1.1 416 Requested Range Not Satisfiable');
exit;
}
}
else
{
$range = '';
}
//figure out download piece from range (if set)
list($seek_start, $seek_end) = explode('-', $range, 2);
//set start and end based on range (if set), else set defaults
//also check for invalid ranges.
$seek_end = (empty($seek_end)) ? ($file_size - 1) : min(abs(intval($seek_end)),($file_size - 1));
$seek_start = (empty($seek_start) || $seek_end < abs(intval($seek_start))) ? 0 : max(abs(intval($seek_start)),0);
//Only send partial content header if downloading a piece of the file (IE workaround)
if ($seek_start > 0 || $seek_end < ($file_size - 1))
{
header('HTTP/1.1 206 Partial Content');
header('Content-Range: bytes '.$seek_start.'-'.$seek_end.'/'.$file_size);
header('Content-Length: '.($seek_end - $seek_start + 1));
} else {
}
header("Content-Length: $file_size");
header('Accept-Ranges: bytes');
set_time_limit(0);
fseek($file, $seek_start);
while(!feof($file))
{
print(#fread($file, 1024*8));
ob_flush();
flush();
if (connection_status()!=0)
{
#fclose($file);
exit;
}
}
// file save was a success
#fclose($file);
exit;
}
else
{
// file couldn't be opened
header("HTTP/1.0 500 Internal Server Error");
exit;
}
}
else
{
// file does not exist
header("HTTP/1.0 404 Not Found");
exit;
}
If i set player.setSrc(data); to player.setSrc('../play?song=songs_id'); then it worked fine but i don't want that. Any idea?
Your PHP code is doing all the work to process the desired URL, and you are basically using play?song=songs_id to set headers and send the file via this piece of code:
print(#fread($file, 1024*8));
ob_flush();
flush();
if (connection_status()!= 0)
{
#fclose($file);
exit;
}
As you can see, you are not using any return statement so you can use that URL to play your media. You are trying to even read the media through PHP. That's why if you use player.setSrc('../play?song=songs_id'); your code will work

'save as' box with Javascript/PHP

On my website I have a JavaScript function that using PHP function creates a file locally on my server (same directory as the website files). The name of this file is known only to these JavaScript and PHP functions.
I want to open a regular 'Save As' box to the user to download this file.
Is there a way to do this using Javascript/PHP in a manner that will work for Firefox, Chrome and Explorer/Edge? (Only the Javascript/PHP know the file name)
This is the PHP example:
file_put_contents($filename,$txt);
header('content-type: application/text');
header('content-disposition: attachment; filename=' . $filename);
readfile($filename);
In chrome & firefox it saves automatically and in IE a window opens so if a user has not changed their settings by default will they see the where to save dialog regardless of the browser they're using. go to
https://support.google.com/chrome/answer/95574?hl=en-GB
For more information. You can use php code for downloading the file from your server.
header('content-type: application/[type]');
header('content-disposition: attachment; filename=yourfile.file-extension');
readfile('yourfile.file-extension');
for a large file, you can use
function readfileChunked($filename, $retbytes=true){
$chunksize = 1*(1024*1024);
$buffer = '';
$cnt = 0;
$handle = fopen($filename, 'rb');
if ($handle === false) {
return false;
}
while (!feof($handle)) {
$buffer = fread($handle, $chunksize);
echo $buffer;
ob_flush();
flush();
if ($retbytes) {
$cnt += strlen($buffer);
}
}
$status = fclose($handle);
if ($retbytes && $status) {
return $cnt; // return num. bytes delivered like readfile() does.
}
return $status;
}
header('Pragma: public'); // required
header('Expires: 0'); // no cache
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private',false);
header('Content-Type: application/force-download');
header('Content-Disposition: attachment; filename="'.$name.'"');
header('Content-Transfer-Encoding: binary');
header('Content-Length: '. get_remote_size($url) );
header('Connection: close');
readfileChunked( $url );

Download an image with an ajax request

I have some files on my PHP server inside uploads folder. My problem is the following: I want to send a JSON asynchronous request from my client as to choose one of these files and create with this an image element as to display it in the browser.
JS code
var file_name="test.jpg";
$.ajax({
method:"POST",
dataType:"json",
url:"retrieve_photo.php",
data:{name:file_name},
success: function(data) {
var new_thumb = document.createElement("img");
document.getElementById('dragarea').appendChild(new_thumb);
...
}
})
PHP code (retrieve_photo.php):
<?php
$ds = DIRECTORY_SEPARATOR;
$storeFolder="uploads";
$file_name=$_POST[name];
$files = glob($storeFolder.$ds.$file_name);
if ( false!==$files ) {
....
}
header('Content-type: text/json');
header('Content-type: application/json');
echo json_encode($result);
?>
I do not know what to write as $result feeds data the right way. I 've tried
$result=readfile($storeFolder.$ds.$file_name);
but maybe not correctly.As to conclude I want to use data as to display an image to my browser.
Thank you
Maybe will be better do something like that?:
var image = new Image();
image.src = "blabla";
$(image).on('load', function(){
//do what you want
})
Why do you even use AJAX? Maybe i don't understand)
Since you don't use algorithm or functions in your PHP, you can do everything by Javascript / Jquery :
var img = $("<img />").attr('src', 'uploads/'+ file_name)
.on('load', function() {
if (!this.complete || typeof this.naturalWidth == "undefined") {
alert('Image not found');
} else {
$("#dragarea").append(img);
}
});
document.getElementByI('dragarea').appendChild(new_thumb);
Мaybe you mean? document.getElementById('dragarea').appendChild(new_thumb);
document.getElementById('dragarea').appendChild(new_thumb);
try this in your retrieve_photo.php
$filename = "test.jpg";
//Make sure $filename contains the appropriate path of the photo
$size = getimagesize($filename);
$file = $filename;
if ($size) {
header("Content-type:". $size['mime']);
header("Content-Length: " . filesize($file));
header("Content-Disposition: attachment; filename=$filename");
header('Content-Transfer-Encoding: base64');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Content-Type: application/force-download");
readfile($file);
exit;
}

Generating Files with JavaScript and PHP

I am trying to generate a file to download. With JavaScript I call a PHP file to process my request and send back the result in a way it should be possible to download it. But instead of making it available for download it simply display the code.
PHP
function export()
{
// Get a database object.
$db = JFactory::getDbo();
// Create a new query object.
$query = $db->getQuery(true);
// Select fields to get.
$fields = array(
$db->quoteName('params')
);
// Conditions for which records should be get.
$conditions = array(
$db->quoteName('element') . ' = ' . $db->quote('plugin_name'),
$db->quoteName('folder') . ' = ' . $db->quote('system')
);
// Set the query and load the result.
$query->select($fields)->from($db->quoteName('#__extensions'))->where($conditions);
$db->setQuery($query);
$results = $db->loadResult();
// Namming the filename that will be generated.
$name = 'file_name';
$date = date("Ymd");
$json_name = $name."-".$date;
// Clean the output buffer.
ob_clean();
echo $results;
header('Content-disposition: attachment; filename='.$json_name.'.json');
header('Content-type: application/json');
}
JavaScript
function downloadFile() {
var fd = new FormData();
fd.append('task', 'export');
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", uploadComplete, false);
xhr.open("POST", "my_php_file");
xhr.send(fd);
}
HTML file
<button class="btn btn-primary btn-success" type="button" onclick="downloadFile()"></button>
UPDATE MY CODE
You need to call any header function calls before you output data. Otherwise you will get a headers "Headers already sent" warning, and the headers will not be set.
Example:
...
// Namming the filename that will be generated.
$name = 'file_name';
$date = date("Ymd");
$json_name = $name."-".$date;
header('Content-disposition: attachment; filename='.$json_name.'.json');
header('Content-type: application/json');
// Clean the output buffer.
ob_clean();
echo $results;
An example
<?php
ob_start();
echo "some content to go in a file";
$contentToGoInFile = ob_get_contents(); //this gets the outputted content above and puts it into a varible/buffer
ob_end_clean();
header('Content-disposition: attachment; filename='.$json_name.'.json');
header('Content-type: application/json');
echo $contentToGoInFile;
exit; //stops execution of code below
example with your code
$results = $db->loadResult();
// Namming the filename that will be generated.
$name = 'file_name';
$date = date("Ymd");
$json_name = $name."-".$date;
ob_start();
echo $results;
$contentToGoInFile = ob_get_contents(); //this gets the outputted content above and puts it into a varible/buffer
ob_end_clean();
header('Content-disposition: attachment; filename='.$json_name.'.json');
header('Content-type: application/json');
echo $contentToGoInFile;
exit

Categories

Resources