AngularJS: Uploading file via angular JS - php

My current scenario is: I've doing nesting repetition like follow:
$scope.uploadPic = function(file)
{
alert($scope.taskdetails.id); //task_id e.g 21
alert($rootScope.job_id); //job_id e.g 12
file.upload = Upload.upload(
{
url: 'http://localhost/mobile-data/upload_file.php',
data: {
file: file,
task_id: $scope.taskdetails.id,
job_id: $rootScope.job_id
},
});
file.upload.then(function (response) {
$timeout(function () {
file.result = response.data;
});
}, function (response) {
if (response.status > 0)
$scope.errorMsg = response.status + ': ' + response.data;
}, function (evt) {
// Math.min is to fix IE which reports 200% sometimes
file.progress = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
});
}
but on my upload_file.php i can't receive the values for:
task_id: $scope.taskdetails.id,
job_id: $rootScope.job_id
in console.log they are working fine. but on server side it is not receiving. here is code of my upload_file.php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
header('content-type: application/json; charset=utf-8');
$_POST = json_decode(file_get_contents('php://input'), true);
$task_id = $_POST["task_id"];
$file = $_FILES["file"];
$job_id = $_POST["job_id"];
var_dump($task_id);
var_dump($job_id);
but on var_dump it only print null. Help me to receive the values correctly..

In your php file remove the decode line that is:
$_POST = json_decode(file_get_contents('php://input'), true);
You dont need to decode because you are not receiving data into JSON encoded array...

Related

Php : get formData base64 image string and upload to local folder

I have base64 image string sending in my API calling to a .php file
Request URL :
http://localhost/server/index.php?saveImageToFolder=true?id=1&name=fdsfsdf
My HTML form looke like below
Below is my code for sending base64 from Input type file which is in reactjs
function getBase64(file) {
return new Promise(function (resolve, reject) {
const reader = new FileReader();
reader.onload = function () {
resolve(reader.result);
};
reader.onerror = reject;
reader.readAsDataURL(file);
});
}
const onChangeImage = (e, id, slotname) => {
const formData = new FormData();
formData.append('file', e.target.files[0]);
const fileFound = e.target.type === 'file' && e.target.files[0];
const promise = fileFound && getBase64(fileFound);
promise.then(function(result) {
uploadImage({ 'id': id, 'slotname': slotname, 'slotimage': result });
})
}
And then i have formData in my payload. Below is the complete network tab payload
My index.php
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");
header("Access-Control-Max-Age: 3600");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
include("connect.php");
error_reporting(0);
session_start();
if(isset($_GET['saveImageToFolder'])){
var_dump($_POST['file']); //This is showing NULL
var_dump($_FILES['file']); //This is also showing NULL
$data = $_POST['file'];
list($type, $data) = explode(';', $data);
list(, $data) = explode(',', $data);
$data = base64_decode($data);
file_put_contents('image.png', $data);
}
Image file is creating with PNG and 0KB. Not getting how to fetch values of formData and then further in index.php
const fileFound = e.target.type === 'file' && e.target.files[0];
evaluates to true or false and in the next step you pass a boolean to getBase64() instead of the filename.
const promise = fileFound && getBase64(fileFound);
So change it to
const promise = fileFound && getBase64(file);
instead.

Phonegap returns object Object but echo correct data

I'm making a phone app using PhoneGap with PHP on the server side. the Login function has been working fine, but AJAX returns an error [object Object] while PHP returns the correct value's in JSON.
it's for making a phone app for an existing website and using its database.
the data my PHP prints is correct yet I receive an error response from ajax.
Alert(response)
Gives an [object Object] return value on error
whenever I try
alert(response.val)
I strangely get undefined, but in the network, I can see the printed data is correct in JSON.
{{"user_id":"390","response":"Success"}}
but when I look in the console on my browser I see an unexpected error.
Unexpected parameter ':'
my ajax function is as follows
$(document).ready(function () {
$("#btnLogin").click(function () {
var gebr = $("#login_username").val().trim();
var pass = $("#login_password").val().trim();
var dataString = "username=" + gebr + "&password=" + pass + "&login=";
var msg = "";
$("#message").html("Authenticating...");
if (gebr != "" && pass != "") {
$.ajax({
type: "POST",
data: dataString,
dataType: "json",
//contentType: "application/javascript",
crossDomain: true,
url: "http://url/page/app/index.php?&jsoncallback=?",
headers: "application/json",
success: function (response) {
var user_id = response.user_id;
var success = response.response;
localStorage.setItem("user_id", user_id);
window.location = "home.html";
alert("login successfull");
},
error: function (response) {
$("#message").html("error..");
alert(response);
}
});
} else {
msg = "Please fill all fields!";
$("#message").html(msg);
}
return false;
});
PHP
header('Content-type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
$gebruikersnaam = $_REQUEST['username'];
$wachtwoord = md5($_REQUEST['password']);
$user = [];
//if user and password are filled
if (!empty($gebruikersnaam) && isset($wachtwoord)) {
//checks if user_id has been found
if (!$found_user_id) {
$msg = "user not found!";
print json_encode($msg);
} else {
if (($gebruikersnaam == $user['gebruikersnaam'] && $wachtwoord == $user['wachtwoord']) && ((!empty($user['single_allowed_ip_address_for_login']) && $user['single_allowed_ip_address_for_login'] == $_SERVER['REMOTE_ADDR'])|| empty($user['single_allowed_ip_address_for_login']))) {
//responds with this data
$user_id = $user['user_id'];
$response[] = array(
'user_id' => $user_id,
'response' => 'Success'
);
print json_encode($response);
} else {
$msg = "user is incorrect";
print json_encode($msg);
}
}
}
I have been wanting to get a successful response and saving the user_id in local storage so it can be used on a different page.
Edit:
after using console.log on the response i got an odd object.
​
abort: function abort()​
always: function always()​
catch: function catch()​
done: function add()​
fail: function add()​
getAllResponseHeaders: function getAllResponseHeaders()​
getResponseHeader: function getResponseHeader()​
overrideMimeType: function overrideMimeType()​
pipe: function pipe()​
progress: function add()​
promise: function promise()
​
readyState: 4
​
setRequestHeader: function setRequestHeader()​
state: function state()
​
status: 200
​
statusCode: function statusCode()
​
statusText: "load"
​
then: function then()​
<prototype>: {…
which is strange because none of these functions are made and the only thing which i can recognize is the statuscode.
You need to correct your JSON. {{"user_id":"390","response":"Success"}} is not valid JSON. It needs to be {"user_id":"390","response":"Success"}.
You're getting a strange object in your console.log because your response in the error: function (response)... is actually the jqXHR jQuery object and will not return your response directly in its arguments. Stick with success: function(response)... and output whatever your server sends back.

Ionic 3 - Upload Image, PDF and form data in single HTTP request

I am working on an Ionic 3 app. Where I need to upload the Image file, PDF file and form data in a single HTTP request.
I have tried Cordova file transfer plugin also but for that I have to call multiple requests (one for image and one for PDF), which I don't want to do.
I have tried each and every solution from google, but I couldn't find the right solution because each and every solution is for upload the image.
I am using PHP as backend. Please let me know where I am making the mistake.
This is HTML
<form (ngSubmit)="submitLicence()" [formGroup]="licence" enctype="multipart/form-data">
<ion-list inset>
<ion-item>
<ion-label>Licence Type</ion-label>
<ion-input type="text" formControlName="licence_type" placeholder="Value"></ion-input>
</ion-item>
<ion-item>
<ion-label>State</ion-label>
<ion-input type="text" formControlName="state" placeholder="Value"></ion-input>
</ion-item>
<ion-item>
<ion-label>Year</ion-label>
<ion-input type="number" formControlName="year" placeholder="Value"></ion-input>
</ion-item>
<ion-item>
<ion-label>Select PDF</ion-label>
<ion-icon name="md-add-circle" item-end color="secondary" (click)="selectPDF()"></ion-icon>
</ion-item>
<ion-item>
<ion-label>Take a Photo</ion-label>
<ion-icon name="md-add-circle" item-end color="secondary" (click)="presentActionSheet()"></ion-icon>
</ion-item>
</ion-list>
<div padding>
<button ion-button type="submit" type="submit" [disabled]="!licence.valid" block>Submit</button>
</div>
</form>
These functions are for upload pdf.
selectPDF(){
this.fileChooser.open()
.then(uri =>
{(<any>window).FilePath.resolveNativePath(uri, (result) => {
let loaderPdf = this.loadingCtrl.create({
content: "Uploading PDF..."
});
loaderPdf.present();
// this.fd.append('doc',result);
this.testResponse = result;
this.nativepath = result;
this.readfile(loaderPdf);
})
})
.catch(e =>
this.testResponse = 'Error - '+e);
}
readfile(loaderPdf) {
(<any>window).resolveLocalFileSystemURL(this.nativepath, (res) => {
res.file((resFile) => {
var reader = new FileReader();
// reader.readAsArrayBuffer(resFile);
reader.onloadend = (evt: any) => {
loaderPdf.dismiss();
var src = evt.target.result;
src = src.split("base64,");
var contentAsBase64EncodedString = src[1];
var contentType = src[0].split(':');
this.testResponse = contentType[1].replace(';','');
contentType = JSON.stringify(contentType[1].replace(';',''));
var fileBlob = new Blob([evt.target.result], { type: contentType});
this.fd.append('doc',fileBlob,'doc');
//do what you want to do with the file
}
reader.readAsDataURL(resFile);
})
})
}
These functions are to select images.
public presentActionSheet() {
let actionSheet = this.actionSheetCtrl.create({
title: 'Select Image Source',
buttons: [
{
text: 'Load from Library',
handler: () => {
this.takePicture(this.camera.PictureSourceType.PHOTOLIBRARY);
}
},
{
text: 'Use Camera',
handler: () => {
this.takePicture(this.camera.PictureSourceType.CAMERA);
}
},
{
text: 'Cancel',
role: 'cancel'
}
]
});
actionSheet.present();
}
public takePicture(sourceType) {
let loaderImage = this.loadingCtrl.create({
content: "Uploading Image..."
});
loaderImage.present();
var options = {
quality: 100,
sourceType: sourceType,
saveToPhotoAlbum: false,
correctOrientation: true
};
// Get the data of an image
this.camera.getPicture(options).then((imageData) => {
// Special handling for Android library
this.base64Image = imageData;
this.readImage(loaderImage);
}, (err) => {
this.presentToast('Error while selecting image.');
});
}
readImage(loaderImage) {
(<any>window).resolveLocalFileSystemURL(this.base64Image, (res) => {
res.file((resFile) => {
var reader = new FileReader();
// reader.readAsArrayBuffer(resFile);
reader.onloadend = (evt: any) => {
var src = evt.target.result;
src = src.split("base64,");
var contentAsBase64EncodedString = src[1];
var contentType = src[0].split(':');
this.testResponse = contentType[1].replace(';','');
contentType = JSON.stringify(contentType[1].replace(';',''));
var imageBlob = new Blob([evt.target.result], { type: contentType});
loaderImage.dismiss();
this.fd.append('image',imageBlob,'image');
//do what you want to do with the file
}
reader.readAsDataURL(resFile);
})
})
}
And finally, this function is for post the form.
submitLicence(){
const licenceFormValue = JSON.stringify(this.licence.value);
let loader = this.loadingCtrl.create({
content: "Submitting form..."
});
loader.present();
var lt = this.licence.value.licence_type;
var st = this.licence.value.state;
var yr = this.licence.value.year;
this.fd.append('type',lt);
this.fd.append('state',st);
this.fd.append('year',yr);
this.fd.append('mode','createNewLicence');
this.testResponse = licenceFormValue;
let headers = new HttpHeaders();
headers = headers.set('Content-Type', 'application/json; charset=utf-8');
this.lic = this.httpClient.post('http://website.com/api.php',this.fd,{headers:headers});
this.lic.subscribe(data => {
loader.dismiss();
this.testResponse = JSON.stringify(data);
})
}
This is PHP script to upload data and images as well.
error_reporting(0);
date_default_timezone_set('GMT');
require_once './config/config_live.php';
include_once PATH_FRONT_LIBRARY . 'adodb5/adodb.inc.php';
include_once PATH_FRONT_LIBRARY . "ADODBClass_mysql.php";
include_once PATH_FRONT_LIBRARY_MAILER . "phpmailer/class.phpmailer.php";
include_once PATH_FRONT_LIBRARY_MAILER . "sendEmail.php";
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Credentials: true");
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
header('Access-Control-Max-Age: 1000');
header('Access-Control-Allow-Headers: Content-Type, Content-Range, Content-
Disposition, Content-Description');
if ($_POST['json']) {
$data = json_decode($_POST['json'], true);
} else {
$jsonString = file_get_contents('php://input');
$jsonObj = json_decode($jsonString, true);
$data = $jsonObj;
}
if ($data["key"] == "difsfk") {
NOTE: The PHP API on which I am working is created by another person and I have to write ionic code as per PHP code.
have you tried with ionic native http library
please follow link : https://ionicframework.com/docs/native/http/
in body send your image and file data and other param.
post(url, body, headers)
For example :
let body = new FormData();
body.append(‘image’, imagedata);
body.append(‘pdf’, pdfdata);
body.append(‘desc’, “testing”);
this.http.post(“Your api endpoint”, body, options).subscribe(res => {
console.log(res);
});

Angular/PHP: upload file data in $_POST, not $_FILES

I'm using AngularJS v1.6.1, Apache 2.4.10 on Debian with PHP 5.6.24 and I'm trying to upload a file to my server using $http POST service.
On my php.ini, max file size is set to 8Mo, max post size too, upload file is on, and memory size limit is set to 128Mo.
Form:
<input type="file" accept="application/pdf" id="uploadOT" max-files="1" ng-model="uploadOT" name="uploadOT" valid-file required ng-class="{'md-input-invalid':uploadForm.uploadOT.$error.validFile}" />
Angular directive: (when input content change, get a FileReader object and send file)
myModule.directive('validFile', function() {
return {
require: 'ngModel',
link: function(scope, elt, attrs, ctrl) {
ctrl.$setValidity('validFile', elt.val() !== '');
elt.bind('change', function() {
var file = document.getElementById('uploadOT').files;
var reader = new FileReader();
reader.onload = function(e) {
scope.sendFile(reader, scope.id);
};
scope.showUploadProgress = true;
scope.filename = file[0].name;
reader.readAsBinaryString(file[0]);
ctrl.$setValidity('validFile', elt.val() !== '');
scope.$apply(function() {
ctrl.$setViewValue(elt.val());
ctrl.$render();
});
});
}
};
});
Inside controller:
$scope.sendFile = function(reader, id) {
var fd = new FormData();
fd.append('id', id);
fd.append('file', reader.result);
fd.append('MAX_FILE_SIZE', 8 * 1024 * 1024);
$http.post('api/upload.php', fd, {
headers: {'Content-Type' : undefined },
transformRequest: angular.identity
}).then(function() {
alert('upload success');
}, function() {
$scope.showUploadError = true;
$scope.showUploadProgress = false;
$scope.postError = 'Une erreur inconnue est survenue !';
});
};
On server side (file api/upload.php), I print variables $_POST and $_FILES with print_r().
Why is $_FILES always empty, and my file data is in $_POST['file']?
I can create file from $_POST['file'] data with php function file_put_contents() but I cannot make verifications that I can make with $_FILES. Is it really important (security issues)?
If I change my POST Content-Type to multipart/form-data, the same thing happend.
I presume it's because you forgot to specify the encoding type of your form element.
enctype="multipart/form-data"
So, by default - the browser will assume that the form encoding type is "application/x-www-form-urlencoded" which does not support files in this way. You can still securely send file binary data with the stock encoding method however, this might be where performance and functionality are determining factors to which you choose. I recommend running some tests to confirm which is the fastest. In some cases, the difference will be negligible and will likely be for sake of consistency.
Skip the FileReader API and use the file object directly:
<input type=file files-input ng-model="files" ng-change="upload()" />
The filesInput Directive
angular.module("myApp").directive("filesInput", function() {
return {
require: 'ngModel',
link: function linkFn (scope, elem, attrs, ngModel) {
elem.on("change", function (e) {
ngModel.$setViewValue(elem[0].files, "change");
});
},
};
});
The upload() function
vm.upload = function() {
//var formData = new $window.FormData();
//formData.append("file-0", vm.files[0]);
var config = { headers: { "Content-Type": undefined } };
$http.post(url, vm.files[0], config)
.then(function(response) {
vm.result = "SUCCESS";
}).catch(function(response) {
vm.result = "ERROR "+response.status;
});
};
The XHR API send() method can post either a file object or a FormData object. It is more efficient to send the file object directly as the XHR API uses base64 encoding for the FormData object which has a 33% overhead.
The DEMO on PLNKR.
To make it works, I had to do these modifications:
Directive:
myModule.directive('validFile', function() {
return {
require: 'ngModel',
link: function(scope, elt, attrs, ctrl) {
ctrl.$setValidity('validFile', elt.val() !== '');
elt.bind('change', function() {
var file = document.getElementById('uploadOT').files;
var reader = new FileReader();
reader.onload = function(e) {
scope.sendFile(file[0], scope.OT); ////CHANGE HERE
};
scope.showUploadProgress = true;
scope.filename = file[0].name;
reader.readAsArrayBuffer(file[0]); ////CHANGE HERE
ctrl.$setValidity('validFile', elt.val() !== '');
scope.$apply(function() {
ctrl.$setViewValue(elt.val());
ctrl.$render();
});
});
}
};
});
Inside Controller
$scope.sendFile = function(file, id) {
var fd = new FormData();
fd.append('id', id);
fd.append('file', file);
fd.append('MAX_FILE_SIZE', 8 * 1024 * 1024);
$http({
method: 'POST',
url: 'upload.php',
data: fd,
headers: {'Content-Type': undefined, 'Process-Data': false},
transformRequest: angular.identity
}).then( function() {
console.log('success');
}, function() {
console.log('failure');
});
};

Polling with angularJs

I just want to have polling connection for an current update of my client.
I can't make it work :
var app = angular.module('url', []);
app.factory('Poller', function($http,$q){
return {
poll : function(api){
var deferred = $q.defer();
$http.get(api).then(function (response) {
deferred.resolve(response.data);
});
return deferred.promise;
}
}
});
app.directive('ngBlur', function(){
return function(scope, elem, attrs){
elem.bind('blur', function(){
scope.$apply(attrs.ngBlur);
})
}
});
app.controller('UrlCtrl', function($scope, $filter, $http, $location, Poller){
$scope.myts = Poller.poll('localhost:8888/mytest.php');
$scope.mydate = $scope.myts.then(function(data){
return $filter('date')(data,'yyyy-MM-dd HH:mm:ss Z');
});
var Repeater = function () {
$scope.$apply(function () {
$scope.myts = Poller.poll('localhost:8888/mytest.php');
$scope.mydate = $scope.myts.then(function(data){
return $filter('date')(data,'yyyy-MM-dd HH:mm:ss Z');
});
});
};
var timer = setInterval(Repeater, 1000);
$scope.urls = [];
$http.get("http://localhost:8888/web-service.php")
.success(function(data) {
data.URLs.forEach(function(url){
$scope.urls.push({
name : url.name,
preferred : false
});
})
})
$scope.$watch('urls', function(){
$scope.chosenURL = $filter('filter')($scope.urls, {preferred:true}).length;
$scope.allchecked = !$filter('filter')($scope.urls, {preferred:false}).length;
}, true)
if($location.path() == ''){ $location.path('/')}
$scope.location = $location;
$scope.$watch('location.path()', function(path){
$scope.statusFilter =
(path == '/active') ? {preferred : true} :
null;
});
$scope.removeUrl = function(index){
$scope.urls.splice(index,1);
}
$scope.addUrl = function(){
$scope.urls.push({
name : $scope.newurl,
preferred : false
});
$scope.newurl = '';
}
$scope.editUrl = function(url){
url.editing = false;
}
$scope.checkAllUrl = function(allchecked){
$scope.urls.forEach(function(url){
url.preferred = allchecked;
})
};
});
mytest.php
<?php
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
echo time()*1000;
?>
Here the error I got :
Failed to load resource: net::ERR_UNKNOWN_URL_SCHEME localhost:8888/mytest.php Failed to load resource: the server
responded with a status of 404 (Not Found)
http://localhost:63342/DeliciousJS/js/app.js.map Failed to load
resource: the server responded with a status of 404 (Not Found)
http://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js.map
8Failed to load resource: net::ERR_UNKNOWN_URL_SCHEME
localhost:8888/mytest.php OPTIONS localhost:8888/mytest.php
net::ERR_UNKNOWN_URL_SCHEME angular.min.js:97(anonymous function)
angular.min.js:97o angular.min.js:93l angular.min.js:92l.(anonymous
function) angular.min.js:94poll app.js:7(anonymous function)
app.js:32e.$eval angular.min.js:86e.$apply angular.min.js:86Repeater
app.js:31 OPTIONS localhost:8888/mytest.php
net::ERR_UNKNOWN_URL_SCHEME
Why it can't find the url that is working when I try directly on chrome?
Thx for your help

Categories