I am using Appgyver to try and upload an image to my custom rest server using the built in Cordova FileTransfer plugin.
(ON ANDROID) Pretty much this is all of my code for trying to upload an image to a REST API. I can get the image and display it AND worse, it actually succeeds and fires the callback (and tells me how many bytes are being sent correctly), but for some reason the server is not getting any parameters with the file. It is currently returning an empty array/object as the list of parameters it's receiving.
(ON IOS) Nothing happens as far as callbacks and I have no idea if the server is receiving anything.
I am using Laravel 4.2 with the Dingo API, Intervention Image, and JWT-Auth plugins.
Server code
$scope.addPost = function(title, price, description, id, uri)
{
var fileURL = uri;
//$scope.encoded = toInternalURL(uri);
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);
options.httpMethod = "POST";
//options.mimeType = "image/png";
options.chunkedMode = false;
//options.trustAllHosts = true;
var myToken = JSON.parse(localStorage.getItem("token"));
var headers =
{
'Authorization': 'Bearer ' + myToken + '',
'Content-Type': 'multipart/form-data'
};
options.headers = headers;
var params =
{
item_title: title,
item_price: price,
item_description: description,
category_id: id
};
options.params = serialize(params);
var ft = new FileTransfer();
// name of api is redacted
ft.upload(fileURL, encodeURI("name of api"), $scope.success, $scope.fail, options);
};
$scope.success = function (r)
{
supersonic.logger.log("Code = " + r.responseCode);
supersonic.logger.log(r.response);
//$scope.encoded = r.response;
supersonic.logger.log("Sent = " + r.bytesSent);
$scope.encoded = "SUCCEED";
};
$scope.fail = function (error)
{
$scope.encoded = error.body.toString();
//supersonic.logger.log(error.body.toString());
$scope.encoded = "FAIL";
};
Server Code
public function store() {
return Input::all();
}
The function is so simple because when I use the intervention syntax Image::make('file')..... there is no input called file, and therefore just returns nothing.
Any help would be greatly appreciated.
Related
In my PhoneGap app, I'm trying to upload a file from device to remote server.
I checked on the file details in the device.
I got the fileURL from this:
Error code=1
var fileURL=filePath; //output file:///storage/emulated/0/Download/xport1.csv
var uri = encodeURI("http://www.example.com/upload/upload.php");
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = fileURL.substr(fileURL.lastIndexOf('/')+1); // output xport1.csv
options.mimeType = "text/plain";
options.chunkedMode = true;
var headers = {'headerParam':'headerValue'};
options.headers = headers;
var ft = new FileTransfer();
ft.upload(fileURL, uri, onSuccess, onError, options,true);
I am getting an error has occurred code=1.
In my php file , print_r($_FILES);
How do i get the file url? The file will always be placed in Download folder.
Please help. There are many examples for uploading image but not for other file types.
Update from comment:
function upload() {
filePath = 'file:///storage/emulated/0/Download/xport1.csv';
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFileSystemSuccess, fail);
window.resolveLocalFileSystemURI(filePath, onResolveSuccess, fail);
}
function onResolveSuccess(fileEntry) {
var fileURL = filePath;
var uri = encodeURI('http://www.example.com/upload/upload.php');
var opt = new FileUploadOptions();
ft.upload(fileURL, uri, onSuccess, onErr, opt, true);
}
I hosted my Slim app on AWS Lambda. For my PHP app to work, I followed this tutorial
My app runs fine until I try to submit a form with a POST method. My PHP cannot get the values from the form. When I dumped $_POST and file_get_contents('php://input'), both returned a null.
In the tutorial, Chris (the author) stated that this code spawns the child process and sets a bunch of environment variables which PHP CGI populates into the $_SERVER super global.
var php = spawn('./php-cgi', ['function.php'], {
env: Object.assign({
REDIRECT_STATUS: 200,
REQUEST_METHOD: requestMethod,
SCRIPT_FILENAME: 'function.php',
SCRIPT_NAME: '/function.php',
PATH_INFO: '/',
SERVER_NAME: serverName,
SERVER_PROTOCOL: 'HTTP/1.1',
REQUEST_URI: requestUri
}, headers)
});
I am not familiar with child processes, so I would like to ask if there is a way that I can also populate the $_POST superglobal? Because I think the POST data lives in the event object/variable in my handler function, meaning (I think) my NodeJS wrapper could access the POST data, but it didn't pass it to the PHP CGI?
exports.handler = function(event, context)
here is the full code of my NodeJS wrapper:
var spawn = require('child_process').spawn;
var parseHeaders, parseResponse, parseStatusLine;
parseResponse = function(responseString) {
var headerLines, line, lines, parsedStatusLine, response;
response = {};
lines = responseString.split('\r\n');
parsedStatusLine = parseStatusLine(lines.shift());
response['protocolVersion'] = parsedStatusLine['protocol'];
response['statusCode'] = parsedStatusLine['statusCode'];
response['statusMessage'] = parsedStatusLine['statusMessage'];
headerLines = [];
while (lines.length > 0) {
line = lines.shift();
if (line === "") {
break;
}
headerLines.push(line);
}
response['headers'] = parseHeaders(headerLines);
response['body'] = lines.join('\r\n');
return response;
};
parseHeaders = function(headerLines) {
var headers, key, line, parts, _i, _len;
headers = {};
for (_i = 0, _len = headerLines.length; _i < _len; _i++) {
line = headerLines[_i];
parts = line.split(":");
key = parts.shift();
headers[key] = parts.join(":").trim();
}
return headers;
};
parseStatusLine = function(statusLine) {
var parsed, parts;
parts = statusLine.match(/^(.+) ([0-9]{3}) (.*)$/);
parsed = {};
if (parts !== null) {
parsed['protocol'] = parts[1];
parsed['statusCode'] = parts[2];
parsed['statusMessage'] = parts[3];
}
return parsed;
};
exports.index = function(event, context) {
// Sets some sane defaults here so that this function doesn't fail when it's not handling a HTTP request from
// API Gateway.
var requestMethod = event.httpMethod || 'GET';
var serverName = event.headers ? event.headers.Host : '';
var requestUri = event.path || '';
var headers = {};
// Convert all headers passed by API Gateway into the correct format for PHP CGI. This means converting a header
// such as "X-Test" into "HTTP_X-TEST".
if (event.headers) {
Object.keys(event.headers).map(function (key) {
headers['HTTP_' + key.toUpperCase()] = event.headers[key];
});
}
// Spawn the PHP CGI process with a bunch of environment variables that describe the request.
var php = spawn('./php-cgi', ['slim/public/index.php'], {
env: Object.assign({
REDIRECT_STATUS: 200,
REQUEST_METHOD: requestMethod,
SCRIPT_FILENAME: 'slim/public/index.php',
SCRIPT_NAME: '/index.php',
PATH_INFO: '/',
SERVER_NAME: serverName,
SERVER_PROTOCOL: 'HTTP/1.1',
REQUEST_URI: requestUri
}, headers)
});
// Listen for output on stdout, this is the HTTP response.
var response = '';
php.stdout.on('data', function(data) {
response += data.toString('utf-8');
});
// When the process exists, we should have a complete HTTP response to send back to API Gateway.
php.on('close', function(code) {
// Parses a raw HTTP response into an object that we can manipulate into the required format.
var parsedResponse = parseResponse(response);
// Signals the end of the Lambda function, and passes the provided object back to API Gateway.
context.succeed({
statusCode: parsedResponse.statusCode || 200,
headers: parsedResponse.headers,
body: parsedResponse.body
});
});
};
In some cases it's necessary to set CONTENT_LENGTH and/or CONTENT_TYPE in the environment in order for php-cgi to process $_POST properly. For example (where postBody is a string like "field1=value1&field2=value2"):
var env = {
'SCRIPT_FILENAME': script_path,
'REQUEST_METHOD': 'POST',
'REDIRECT_STATUS': 1,
'CONTENT_TYPE': 'application/x-www-form-urlencoded',
'CONTENT_LENGTH': postBody.length
}
//if the URL has anything after "?", it should appear in $_GET even when the method is "POST"
if(queryString) env['QUERY_STRING'] = queryString;
The post body needs to be input into the stdin of the child.
Here is an async example:
var spawn = require('child_process').spawn;
var phpProcess = spawn (php_cgi_path, [script_path], {'env': env})
phpProcess.stdin.write( postBody );
var outputBuffer = [];
phpProcess.stdout.on('data', function(data) {
outputBuffer.push (data.toString());
})
phpProcess.stdout.on('end', function( ) {
var phpOutput = outputBuffer.join('') ;
// process php output
});
It's also possible to give the input data in a synchronous way, for example:
var spawnSync = require('child_process').spawnSync;
var phpProcessSync = spawnSync (php_cgi_path, [script_path], {'env': env, 'input': postBody})
var phpOutput = phpProcessSync.stdout.toString()
// process php output
Again the post data is input separately from "env".
It's also possible to modify the script so that it populates $_FILES as well.
For example, one can use Uint8Array (instead of string) to store post body, then set 'CONTENT_TYPE' to request.headers['content-type'] (Then we would have for example "Content-Type:multipart/form-data; boundary=----WebKitFormBoundarynGa8p8HMIQ8kWQLA")then use phpProcess.stdin.write( Buffer.from(postBody) );
It will have "tmp_name" etc in the $_FILES variable.
I'm using the cordova file-transfer plugin in order for users to upload pictures within my app.
My code works perfectly when making a normal http request to the php page on my server.
I would like to make a secure request so am trying to use https however I am getting a 406 error (see screenshot for error details)
All other ajax requests I am making within the app are working successfully using https.
I am currently not sending any headers when making the request however there is an option to do this using the file-transfer plugin.
I have looked into how I can solve this error (for example this question here) however am still uncertain as to what I need to do in my case.
I was wondering can you help determine what headers I need?
Here is my code:
Javascript
function uploadProfilePic(){
var token = localStorage.getItem("usertoken");
var defs = [];
var def = $.Deferred();
function win(r) {
if($.trim(r.response) === "0") {
alert("Sorry! We have encountered an error");
def.resolve(0);
}else{
def.resolve(1);
}
}
function fail(error) {
//upload of pic failed.
alert("Sorry! We have encountered an error: " + JSON.stringify(error));
def.resolve(0);
}
var uri = encodeURI("https://www.example.com/update_profile_pic.php");
var options = new FileUploadOptions();
options.fileKey="profile_pic_image_file";
options.mimeType="image/jpeg";
var params = new Object();
params.usertoken = token;
params.app_root_url = app_root_url;
//not sure what headers to add here.
//var headers={'headerParam':'headerValue'};
//options.headers = headers;
options.params = params;
var ft = new FileTransfer();
ft.onprogress = function(progressEvent){
if(progressEvent.lengthComputable){
loadingStatus.setPercentage(progressEvent.loaded / progressEvent.total);
}else{
loadingStatus.increment();
}
};
ft.upload($ESAPI.encoder().encodeForURL(profileImage), uri, win, fail, options);
defs.push(def.promise());
$.when.apply($, defs).then(function() {
//pic uploaded fine
});
}
PHP (upload_profile_pic.php)
header("Access-Control-Allow-Origin: *");
if(isset($_FILES['profile_pic_image_file'])){
$data['profile_image_is_set'] = true;
//do stuff with profile image here
echo json_encode($data);
}else{
$data['profile_image_is_set'] = false;
//image not set
echo json_encode($data);
}
I'm having a problem with sending a file from an app I'm developing with phonegap.
I'm new to phonegap, so I might be trying to solve this in an entirely wrong way, so let me describe the the end goal first.
I'm developing a car rental app, I need to make a contact form, so users can leave an order to rent a car.
The form requires user to put in some basic information, like name and phone number, and also attach a photo or a scan of driver's license.
I was able to figure out the basic info part. I'm using $.ajax dataType: 'jsonp', to send the data to the server and then simply e-mail it to my client's address.
But I can find a way to send the file to the server.
I'm using an input[type=file] field to let the user choose what file to upload.
I've tried uploading file using FileTransfer, but apparently input[type=file] gives you some fake file path, that can't be directly used by FileTransfer.upload()
Problem is, I can't understand how can I get a proper file path for FileTransfer.upload function.
I've tried doing it another way, by reading the file using FileReader.
I tried reading the file and setting an image src to the result, but it doesn't work (it show broken image icon instead of an image, the same code works on PC).
I also tried to output it as text, that does output some data (so why doesn't it work for image src?).
Because I did manage to output the data read from the file as text I thought I will send that to the server and save it.
So here is how the code would look like:
On input change I read the file into a global variable
$(".file1").change(function(e){
var caster = e.target;
var files = caster.files;
if(FileReader && files && files.length) {
var fr = new FileReader();
fr.onloadend = function(e) {
//$(".image").attr("src",e.target.result);
window.file1base64 = e.target.result;
}
fr.readAsDataURL(files[0]);
}
});
Then, when user presses a button, I run FileTransfer.upload and then check every 0.1 seconds, whether the file upload is complete
function uploadSuccess(r) {
$(".output").append(" Success ");
window.fileStatus = true;
}
function uploadError(error) {
$(".output").append(" Error "+error.code+" ");
window.fileStatus = true;
window.fileError = error.code;
}
function uploadFile() {
$(".output").append(" uploadFile ");
file = $('.file1').val().split('\\').pop();
$(".output").append(" File-"+file+" ");
if(file){
$(".output").append(" fileExists ");
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = file;
options.mimeType = "image/jpeg";
options.chunkedMode = false;
options.headers = {
Connection: "close"
};
$(".output").append(" FileUploadOptions ");
window.fileStatus = false;
window.fileError = '';
//fileuri = $(".image").attr("src");
fileuri = window.file1base64;
$(".output").append(" fileuri ");
var ft = new FileTransfer();
ft.upload(fileuri, encodeURI("http://***.***/savefile.php"), uploadSuccess, uploadError, options);
$(".output").append(" upload ");
checkFile();
}
}
function checkFile() {
if(!window.fileStatus) {
$(".output").append(" check ");
setTimeout(checkFile, 100);
return;
}
}
After some checks, it prints out Error 3 and I can't figure out what that means or how to fix it.
Server side code is simply this:
Get the file and save it
$dir_name = dirname(__FILE__)."/uploadedimages/";
move_uploaded_file($_FILES["file"]["tmp_name"], $dir_name."test.txt");
But no file is created on the server.
use the FormData object to get the form data (including input file) and submit it this way:
var data = new FormData($('#yourFormID')[0]);
$.ajax({
url: serverURL,
data: data,
cache:false,
contentType: false,
processData: false,
type: 'POST',
error: function(jqXHR,textStatus,errorThrown){
},
success: function(data){
}
});
You should set the FILEURL in some variable and image in some html image element and then use it to transfer the image.
like this:
function onPgCameraSuccess(imageData) {
fileEntry.file(
function(fileObj) {
var previewImage= document.getElementById('SomeImageElement');
fileName=imageData.substr(imageData.lastIndexOf('/')+1);
fileURL=imageData;
previewImage.src =imageData;
$('#SomeTextBox').val(fileName);
});
}
function SubmitPhoto(){
var uOptions = new FileUploadOptions();
var ft = new FileTransfer();
uOptions .fileKey = "keyofyourfileonserver";
uOptions .fileName = fileName;
uOptions .mimeType = "image/jpeg";
uOptions .httpMethod = "POST";
uOptions .params = params;
ft.upload(fileURL,
urlofsvc,
photoSuccess,
photoFail,
uOptions,
true
);}
I am new to phone gap/cordova and PHP. I created a phone gap/cordova application to upload camera taken image to server.The server uniquely renames the image according to some timestamp code and it has to return that image name back to the app.I have pretty well uploaded the image but I need to retrieve back that image name data echoed back by the server.On success upload, when I tried to alert the data that is returned back by the server, it is alerting [object object].I need to retrieve the value.How can it be possible.My code at the client side is given below.
var pictureSource; // picture source
var destinationType; // sets the format of returned value
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
pictureSource = navigator.camera.PictureSourceType;
destinationType = navigator.camera.DestinationType;
}
function clearCache() {
navigator.camera.cleanup();
}
var retries = 0;
function onCapturePhoto(fileURI) {
var win = function (r) {
clearCache();
retries = 0;
alert('Done! message returned back is '+r);
}
var fail = function (error) {
if (retries == 0) {
retries ++
setTimeout(function() {
onCapturePhoto(fileURI)
}, 1000)
} else {
retries = 0;
clearCache();
alert('Ups. Something wrong happens!');
}
}
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = fileURI.substr(fileURI.lastIndexOf('/') + 1);
options.mimeType = "image/jpeg";
var params=new param();
param.client_device_id=device.uuid;
options.params = params; // if we need to send parameters to the server request
var ft = new FileTransfer();
ft.upload(fileURI, encodeURI("http://host/upload.php"), win, fail, options);
}
function capturePhoto() {
navigator.camera.getPicture(onCapturePhoto, onFail, {
quality: 100,
destinationType: destinationType.FILE_URI
});
}
function onFail(message) {
alert('Failed because: ' + message);
}
The code for the upload.php is given below
<?php
if (!file_exists($_POST["client_device_id"])) {
mkdir($_POST["client_device_id"], 0777, true);
}
$date = new DateTime();
$timeStamp=$date->getTimestamp() -1435930688;
move_uploaded_file($_FILES["file"]["tmp_name"], 'f:\\xampp\\htdocs\\FileUpload\\'.$_POST["client_device_id"]."\\".$timeStamp.'.jpg');
echo $timeStamp.".jpg";
?>
The problem is that after successful upload in the device it is alerting 'Done! message returned back is [object object]'.I need to get the value.Please help me on it.
I figured out the answer myself.Just want to share with you all.I used alert(JSON.stringify(r)).Now I know the format of the returned json object .Knowing that I have easily printed out the image name.r.response helped me retrieve the generated image name.