Please I want to send some text data with file upload(ng2 file upload) in angular ionic. I am new to angular and ionic as well. I have tried so many options but I don't seem to get a way out. I am using Php as a backend.I am able to send the file only but not the input data like username. Meanwhile I am able to log the input data that's username on the console but the server response is null. And it never inserts in my database. This is my code.
public fileUploader: FileUploader = new FileUploader({});
ngOnInit() {
this.fileUploader = new FileUploader({ url: "http://localhost/paat/server/post.php"});
this.fileUploader.onBuildItemForm = (fileItem: any, form: FormData): any => {
form.append('body', this.body);
form.append('username', this.username);
// Add file to upload
form.append('file', fileItem);
fileItem.withCredentials = false;
return { fileItem, form };
};
}
fileOverBase(event): void {
this.hasBaseDropZoneOver = event;
}
//return files from ng2 upload
getFiles(): FileLikeObject[] {
return this.fileUploader.queue.map((fileItem) => {
return fileItem.file;
});
}
// the upload method where the post to server is made
uploadFiles() {
let bodys = {
body:this.body,
username:this.username,
};
let files = this.getFiles();
let requests = [];
files.forEach((file) => {
let formData = new FormData();
formData.append('file' , file.rawFile, file.name);
formData.append('body' , this.body);
formData.append('username' , this.username);
requests.push(this.uploadingService.uploadFormData(formData));
});
concat(...requests).subscribe(
(res) => {
console.log(res);
console.log(this.body);
console.log(this.username);
console.log(this.file.name);
},
(err) => {
console.log(err);
}
);
}
this is my uploadservice.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class UploadingService {
API_SERVER: string = "http://localhost/paat/server/post.php";
constructor(private http: HttpClient) { }
public uploadFormData(formData) {
return this.http.post<any>(`${this.API_SERVER}`, formData);
}
}
This is my backend code:
<?php
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods:POST,GET,PUT,DELETE");
header("Access-Control-Max-Age:86400");
header("Access-Control-Allow-Headers: Content-Type,Access-Control-Allow-Headers,Authorization,X-Requested-With");
$con = mysqli_connect("localhost", "root", "", "social");
$postjson = json_decode(file_get_contents('php://input'), true);
$filename = $_FILES['file']['name'];
$meta = $_POST;
$targetDir = "assets/images/posts/";
$destination = $targetDir . $filename;
move_uploaded_file( $_FILES['file']['tmp_name'] , $destination );
$body = $postjson['body'];
$date_added = date("Y-m-d H:i:s");
//get username
$added_by = $postjson['username'];
//if user is on own profile, user_to is 'none'
$targetfile = $destination;
$user_to ="none";
$query = mysqli_query($con,"INSERT INTO posts VALUES(NULL, '$body', '$added_by', '$user_to', '$date_added', 'no', 'no', '0', '$targetfile')");
What am I doing wrong? Please help.
I have found out what I was doing wrong. The problem was with my backend code. It was the way I was retrieving the formdata values from the request. So I changed
$body = $postjson['body'];
$added_by = $postjson['username'];
to
$body = $_POST['body'];
$added_by = $_POST['username'];
Also I modified my ngOnInit() method and the instance of fileuploader method to
public fileUploader: FileUploader = new FileUploader({ url: "http://localhost/paat/server/post.php"});
ngOnInit() {
this.fileUploader.onBuildItemForm = (fileItem: any, form: FormData): any => {
form.append('body', this.body);
// Add file to upload
form.append('file', fileItem);
form.append('username', this.username);
fileItem.withCredentials = false;
return { fileItem, form };
};
}
and it now works.
Related
we created an ionic app which captures video but we are facing challenges saving this video to a directory in on the server. I have searched online for this but couldn't find a tutorial about it.
On the code below, the video name was saved in the videos folder instead of the actual video
//Upload video php part
$postjson = json_decode(file_get_contents('php://input'), true);
if(!empty($postjson['video'])){
$video = $postjson['video'];
$now = DateTime::createFromFormat('U.u', microtime(true));
$id = $now -> format('YmdHisu');
$upload_folder = "videos";
$path ="$upload_folder/$id.mp4";
$actualpath = "http://url/incident/api/$path";
file_put_contents($path,$video);
}
On the ionic part, I have this:
captureVideo() {
let options: CaptureVideoOptions = {
limit: 1,
duration: 120
}
this.mediaCapture.captureVideo(options).then((res: MediaFile[]) => {
let capturedFile = res[0];
let fileName = capturedFile.name;
let dir = capturedFile['localURL'].split('/');
dir.pop();
let fromDirectory = dir.join('/');
var toDirectory = this.file.dataDirectory;
this.ivideo = fileName;
this.viddir = dir;
console.log("video captured "+this.ivideo);
this.file.copyFile(fromDirectory , fileName , toDirectory , fileName).then((res) => {
this.storeMediaFiles([{name: fileName, size: capturedFile.size}]);
},err => {
console.log('err: ', err);
});
},
(err: CaptureError) => console.error(err));
}
Sending to the server using post method in code summary:
var headers = new Headers();
headers.append('Content-Type', 'application/json' );
//headers.append('Access-Control-Allow-Methods', 'POST' );
headers.append('Content-Type', 'multipart/form-data');
let options = new RequestOptions({ headers: headers });
let data = {
aksi : 'insert_incident',
title: this.title.value,
descr: this.descr.value,
images : this.cameraData,
video: this.ivideo,
};
this.http.post(this.global.serverAddress+"api/getCategories.php", data, options)
.map(res => res.json())
.subscribe(res => {
loader.dismiss()
if(res=="Done"){
let alert = this.alertCtrl.create({
title:"Done",
subTitle: "Sent",
buttons: ['OK']
});
alert.present();
}else
{
let alert = this.alertCtrl.create({
title:"ERROR",
subTitle:(res),
buttons: ['OK']
});
alert.present();
}
}
I am able to consume the php endpoint from postman. I try to do the same from angular post, I get this error - Http failure during parsing for. Even though everything looks perfect to me, the problem is surprising. Here is my snippet
php file
<?php
header('Access-Control-Allow-Origin: *');
// check for post
if ($_SERVER['REQUEST_METHOD']=='POST') {
$name = $_POST['name'];
$email = $_POST['email'];
$subject = $_POST['subject'];
$message = $_POST['message'];
// include db connect class
require_once __DIR__ . '/db_connect.php';
// connecting to db
$conn = new db_CONNECT();
$cone=$conn->con;
//escpae the strings to be inserted to DB
$escapedname = mysqli_real_escape_string($cone, $name);
$escapedemail = mysqli_real_escape_string($cone, $email);
$escapedsubject= mysqli_real_escape_string($cone, $subject);
$escapedmessage = mysqli_real_escape_string($cone, $message);
// mysql inserting a new row
$sql = "INSERT INTO contacts(name, email, subject, message) VALUES ('$escapedname', '$escapedemail', '$escapedsubject', '$escapedmessage')";
// $result= $cone -> query($sql);
// $affected = $cone -> affected_rows;
if (mysqli_query($cone,$sql)) {
echo "Information saved successfully.";
} else {
echo "Not successful";
}
} else {
echo "Some field missing.";
}
?>
here is the angular snippet
saveContactDetails = function () {
this.proceed = true;
this.success = false;
const myheader = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
data.append('name', this.contactDeJson.name);
data.append('email', this.contactDeJson.email);
data.append('subject', this.contactDeJson.subject);
data.append('message', this.contactDeJson.message);
this.http
.post('http://localhost:80/'+'api/create_contact.php', data.toString(), {headers: myheader})
Please why am I getting this error
{"headers":{"normalizedNames":{},"lazyUpdate":null},"status":200,"statusText":"OK","url":"http://localhost/api/create_contact.php","ok":false,"name":"HttpErrorResponse","message":"Http failure during parsing for http://localhost/api/create_contact.php",
I believe the issue is that your angular script is expecting a json response (the default responseType), but not receiving the correct headers or data. In stead of just echoing out your result in php, I would make a function that can handle sending the response. Something like this:
function sendJsonResponse(data, status = 200) {
header('Content-Type: application/json', true, status);
echo json_encode($data);
exit();
}
In stead of of doing this:
echo "Not successful";
You can now do this:
sendJsonResponse("Not successful", 500);
This should give you more valuable information in the frontend. And the response should now be formatted correctly, and no longer produce the parse error in angular that you are getting now.
I believe you are trying to send some query parameters using data variable. You could actually send a JS object as the parameters. Try the following
private saveContactDetails() {
this.proceed = true;
this.success = false;
const myheader = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded');
const data = {
'name': this.contactDeJson.name,
'email': this.contactDeJson.email,
'subject': this.contactDeJson.subject,
'message': this.contactDeJson.message
}
this.http.post('http://localhost:80/'+'api/create_contact.php', { params: data }, { headers: myheader })
}
I have code that sends an image to my server and everything works fine. However i am now truing to send a file to my server using an input tag in ionic However i cant seem to get it working.
I get an error from the php file saying undefined index 'file'
HTML
<ion-col>
<ion-label>Add a File</ion-label>
<ion-input type='file' [(ngModel)]="fileName"></ion-input>
</ion-col>
TS file
addFile() {
this.addService.addFile(this.fileName).subscribe(res => {
console.log(res);
});
}
service
addFile(file) {
let headers = new HttpHeaders();
// headers = headers.set('Content-Type', 'application/json');
headers = headers.set('Authorization', '' + this.token);
const formData = new FormData();
formData.append('file', file);
return this.http.post<any>('http://domain.fileUpload.php', formData, {headers});
}
PHP API
$target_path = "files/";
$target_path = $target_path . basename( $_FILES['file']['name']);
$findDate = date("Y-m-d");
if (move_uploaded_file($_FILES['file']['tmp_name'], $target_path)) {
header('Content-type: application/json');
$data = ['success' => true, 'message' => 'Upload and move success'];
echo json_encode( $data );
} else {
header('Content-type: application/json');
$data = ['success' => false, 'message' => 'There was an error uploading the file (folder), please try again!'];
echo json_encode( $data );
}
uploadMethod
uploadFile: ''; // from ngModel
fileUpload(path) {
const fileTransfer: FileTransferObject = this.transfer.create();
let options: FileUploadOptions = {
fileKey: 'file',
fileName: '.png',
chunkedMode: false,
};
console.log(this.uploadFile);
fileTransfer
.upload(this.uploadFile, 'http://domain/fileUpload.php',
options
)
.then(
data => {
console.log(data + 'Uploaded Successfully');
// console.log(JSON.parse(data.));
// let res = JSON.parse(data);
let res = data;
if (res['success']) {
console.log('True');
}
},
err => {
console.log(err);
}
);
}
Blow is the Example Code:
import { Platform } from 'ionic-angular';
checkPlatform: boolean = fasle;
constructor(public plt: Platform) {
if (this.plt.is('ios')) {
this.checkPlatform == true; // if platform ios this will be true
}
if (this.plt.is('android')) {
this.checkPlatform == true; // if platform androidthis will be true
}
}
imageUpload(path) {
const fileTransfer: FileTransferObject = this.transfer.create();
let options: FileUploadOptions = {
fileKey: 'image',
fileName: '.png',
chunkedMode: false,
//mimeType: "image/jpeg",
}
fileTransfer.upload(path, 'https://yourDomain.com/api/imageUpload', options)
.then((data) => {
console.log(data+" Uploaded Successfully");
console.log(JSON.parse(data.response));
let res = JSON.parse(data.response);
if (res.success == true) {
// do whats ever you want to do
}
}, (err) => {
console.log(err);
});
}
Pass the cordova file path as parameter in this function.
inside you HTML template show buttons or input type like this:
<input type="file" *ngIf="checkPlatform == true">
if you see this you can notice allowed types are :
export type TextFieldTypes = 'date' | 'email' | 'number' | 'password' | 'search' | 'tel' | 'text' | 'url' | 'time';
if you want to upload files follow this link i think you will find the answer
I check your code and as i see file added to FormData is filename with string Type, not File or Blob Data Type. So in this case it will not send file into $_FILES, it actually send its value to $_POST in your PHP Server. In summary, File and Blob Type will be sent to $_FILES, other data types will be sent to the appropriate global variables.
There is also a good example on how to validate your file in PHP Server: https://www.php.net/manual/en/features.file-upload.php
I'm using PHP for a project that needs to be able to upload images from a gallery. For now I'm trying this:
I'm trying to pick image from gallery using httpClient and upload it to php serve. What works from is - pick image, convert mediafile to base64, but when it comes to php it recieves image file but doesn't add it to folder and always returns failed upload.
Where am I mistaken?
Here is my code:
private async void browse_image(object sender, EventArgs e)
{
await CrossMedia.Current.Initialize();
var file = await CrossMedia.Current.PickPhotoAsync();
MF = file;
if (file == null)
return;
string[] stringSeparators = new string[] { "." };
var result = file.Path.Split(stringSeparators, StringSplitOptions.None);
img_path.Text = u.Username + code.Text + "." + result[1];
var stream = file.GetStream();
profile.Source = ImageSource.FromStream(() =>
{
return stream;
});
}
public bool convert_image_to64(){
var stream = MF.GetStream();
byte[] filebytearray = new byte[stream.Length];
stream.Read(filebytearray, 0, (int)stream.Length);
base64 = Convert.ToBase64String(filebytearray);
if(String.IsNullOrEmpty(base64)){
return false;
}
return true;
}
async Task upload_profile_page()
{
try
{
string result = "";
var postData = new List<KeyValuePair<string, string>>();
postData.Add(new KeyValuePair<string, string>("image", base64));
postData.Add(new KeyValuePair<string, string>("filename", img_path.Text));
var stringPayload = JsonConvert.SerializeObject(postData);
var content = new StringContent(stringPayload, Encoding.UTF8, "application/json");
await DisplayAlert("", content.ToString(), "ok");
HttpClient client = new HttpClient();
var response = await client.PostAsync("http://example.com/upload_app.php", content);
var FinalJSonResult =. (JArray)JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().Result);
if (FinalJSonResult.Count > 0)
{
var j = (JObject)FinalJSonResult[0];
result = j.GetValue("result").ToString();
if (result.Equals("0"))
{
await DisplayAlert("0 ->", "failed to upload", "ok");
}
else if (result.Equals("1"))
{
await DisplayAlert("1 ->", "uploaded image successffully", "ok");
}
else
{
await DisplayAlert("1 ->", result, "ok");
}
}
else
{
await DisplayAlert("Error", "Empty result" + "\n" + "size of returned array:- " + FinalJSonResult.Count.ToString(), "Ok");
}
}
catch (Exception ex)
{
await DisplayAlert("Error", ex.ToString(), "Ok");
return;
}
}
<?php // read JSon input
$data_back = json_decode(file_get_contents('php://input'));
// set json string to php variables
$base = $data_back->{"image"};
$filename = $data_back->{"filename"};
$binary=base64_decode($base);
$result1 = array();
header("Content-type: application/json");
try{ // Decode Image
$binary=base64_decode($base);
header('Content-Type: bitmap; charset=utf-8');
$result1 = array();
// Images will be saved under '.../uplodedimages' folder
$file = fopen('.../uplodedimages/'.$filename, 'wb');
// Create File
if(fwrite($file, $binary)==false){
array_push($result1,array( 'result'=>"0"));
}else{
$result1 = array();
array_push($result1,array( 'result'=>"1"));
}
fclose($file);
}catch(Exception $e) {
array_push($result1,array( 'result'=>$e));
}
echo json_encode($result1,JSON_UNESCAPED_UNICODE);
?>
Please I have been trying to upload pictures from a xamarin form application to a php server but seems not to be working. The server receives an empty $_FILES request. This is the c# code.
public async Task<bool> Upload(MediaFile mediaFile, string filename)
{
byte[] bitmapData;
var stream = new MemoryStream();
mediaFile.GetStream().CopyTo(stream);
bitmapData = stream.ToArray();
var fileContent = new ByteArrayContent(bitmapData);
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "fileUpload",
FileName = filename
};
string boundary = "---8393774hhy37373773";
MultipartFormDataContent multipartContent = new MultipartFormDataContent(boundary);
multipartContent.Add(fileContent);
HttpClient httpClient = new HttpClient();
HttpResponseMessage response = await httpClient.PostAsync("http://www.url.com/upload.php", multipartContent);
response.EnsureSuccessStatusCode();
if (response.IsSuccessStatusCode)
{
string content = await response.Content.ReadAsStringAsync();
return true;
}
return false;
}
Below is the php file to receive the uploaded image. I tried to save the content of the posted image to file but the file only has an empty array and always return "failure". Please what am i missing wrong? I have searched the web but cant seem to understand the problem.
$uploads_dir = 'uploads/';
$req_dump = print_r( $_FILES, true );
$fp = file_put_contents( 'data.txt', $req_dump );
if (isset($_FILES["fileUpload"]["tmp_name"]) AND is_uploaded_file($_FILES["fileUpload"]["tmp_name"]))
{
$tmp_name = $_FILES["fileUpload"]["tmp_name"];
$name = $_FILES["fileUpload"]["name"];
$Result = move_uploaded_file($tmp_name, "$uploads_dir/$name");
echo "Success";
}
else
{
echo "Failure";
}
The AND operator is really not a good choice for you. (On line 4).
Sometimes it shows some really unexpected behaviour. (I can refer you to 'AND' vs '&&' as operator for more info).
If you want a logical AND use the && operator instead.
The line would be
if (isset($_FILES["fileUpload"]["tmp_name"]) && is_uploaded_file($_FILES["fileUpload"]["tmp_name"]))
I know this is an old post but this is how I upload an image from Xamarin Forms to PHP
http://gjhdigital.com/xamarin/xamarin-forms-upload-image-to-php/
Xamarin c# code
using Plugin.Media;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace UploadPicToServer
{
// Learn more about making custom code visible in the Xamarin.Forms previewer
// by visiting https://aka.ms/xamarinforms-previewer
[DesignTimeVisible(false)]
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private async void btnUpload_Clicked(object sender, EventArgs e)
{
if (!CrossMedia.Current.IsPickPhotoSupported)
{
await DisplayAlert("Photos Not Supported", ":( Permission not granted to photos.", "OK");
return;
}
var file = await Plugin.Media.CrossMedia.Current.PickPhotoAsync(new Plugin.Media.Abstractions.PickMediaOptions
{
PhotoSize = Plugin.Media.Abstractions.PhotoSize.Medium,
});
if (file == null)
return;
string fileName = file.Path;
image.Source = ImageSource.FromStream(() =>
{
var stream = file.GetStream();
file.Dispose();
return stream;
});
//UploadImage1(file.AlbumPath);
UploadImage(file.GetStream(), fileName);
}
private async void UploadImage(Stream mfile, string fileName)
{
int authorID = 2;
string username = "yourusername";
var url = "https://yourwebsite.com/ba-add-profile-pic.php";
url += "?id="+ authorID +"&username="+ username; //any parameters you want to send to the php page.
try
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://yourwebsite.com/");
MultipartFormDataContent form = new MultipartFormDataContent();
//HttpContent content = new StringContent("fileToUpload");
//form.Add(content, "fileToUpload");
var stream = mfile;
StreamContent content = new StreamContent(stream);
//get file's ext
string fileExt = fileName.Substring(fileName.Length - 4);
string fName = "User-Name-Here-123" + fileExt.ToLower();
content.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
Name = "fileToUpload",
FileName = fName
};
form.Add(content);
var response = await client.PostAsync(url, form);
var result = response.Content.ReadAsStringAsync().Result;
}
catch (Exception e)
{
//debug
Debug.WriteLine("Exception Caught: " + e.ToString());
return;
}
}
public static byte[] ToArray(Stream s)
{
if (s == null)
throw new ArgumentNullException(nameof(s));
if (!s.CanRead)
throw new ArgumentException("Stream cannot be read");
MemoryStream ms = s as MemoryStream;
if (ms != null)
return ms.ToArray();
long pos = s.CanSeek ? s.Position : 0L;
if (pos != 0L)
s.Seek(0, SeekOrigin.Begin);
byte[] result = new byte[s.Length];
s.Read(result, 0, result.Length);
if (s.CanSeek)
s.Seek(pos, SeekOrigin.Begin);
return result;
}
}
}
PHP code
//parameters send in via querystring
if (!isset($_REQUEST['author']) || !isset($_REQUEST['username']) ) {
die('{"status" : "Bad", "reason" : "Invalid Access"}');
}
$userID = $_REQUEST['author'];
$isGood = false;
try{
$uploaddir = '../someFolderToStoreTheImage/';
$fileName = basename($_FILES['fileToUpload']['name']);
$uploadfile = $uploaddir . basename($_FILES['fileToUpload']['name']);
//CHECK IF ITS AN IMAGE OR NOT
$allowed_types = array ('image/jpeg', 'image/png', 'image/bmp', 'image/gif' );
$fileInfo = finfo_open(FILEINFO_MIME_TYPE);
$detected_type = finfo_file( $fileInfo, $_FILES['fileToUpload']['tmp_name'] );
if ( !in_array($detected_type, $allowed_types) ) {
die ( '{"status" : "Bad", "reason" : "Not a valid image"}' );
}
//
if (move_uploaded_file($_FILES['fileToUpload']['tmp_name'], $uploadfile)) {
//echo "File is valid, and was successfully uploaded.\n";
echo '{"status" : "Success", "reason" "'. $fileName .'"}';
$isGood = true;
} else {
//echo "Possible file upload attack!\n";
echo '{"status" : "Bad", "reason" : "Unable to Upload Profile Image"}';
}
}
catch(Exception $e) {
echo '{"status" : "Bad", "reason" : "'.$e->getMessage().'"}';
}