Im following some tutorial to upload file on server by php api. I need to send some data with file. Like with file i want to send a name. So it will generate folder by that name and save file in that folder.
home.ts
onFileSelect(event) {
if (event.target.files.length > 0) {
const file = event.target.files[0];
this.form.get('avatar').setValue(file);
}
}
onSubmit() {
console.log(this.backUrl);
name = this.backUrl;
console.log(name);
const formData = new FormData();
formData.append('avatar', this.form.get('avatar').value);
this.uploadService.uploadFile(formData).subscribe(
(res) => {
this.uploadResponse = res;
console.log(res);
},
(err) => {
console.log(err);
}
);
}
service.ts
public uploadFile(data,) {
let uploadURL = 'http://api.igiinsurance.com.pk:8888/file_upload/upload.php';
return this.httpClient.post<any>(uploadURL, data);
}
upload.php
<?php
header('Content-Type: application/json; charset=utf-8');
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: PUT, GET, POST");
$response = array();
$upload_dir = 'uploads';
$server_url = 'http://api.igiinsurance.com.pk:8888';
if($_FILES['avatar'])
{
$avatar_name = $_FILES["avatar"]["name"];
$avatar_tmp_name = $_FILES["avatar"]["tmp_name"];
$error = $_FILES["avatar"]["error"];
if($error > 0){
$response = array(
"status" => "error",
"error" => true,
"message" => "Error uploading the file!"
);
}else
{
$random_name = rand(1000,1000000)."-".$avatar_name;
$upload_name = $upload_dir.strtolower($random_name);
$upload_name = preg_replace('/\s+/', '-', $upload_name);
if(move_uploaded_file($avatar_tmp_name , $upload_name)) {
mkdir("upload/testing3");
$response = array(
"status" => "success",
"error" => false,
"message" => "File uploaded successfully",
"url" => $server_url."/".$upload_name
);
}else
{
$response = array(
"status" => "error",
"error" => true,
"message" => "Error uploading the file!"
);
}
}
}else{
$response = array(
"status" => "error",
"error" => true,
"message" => "No file was sent!"
);
}
echo json_encode($response);
?>
I want to send name with file. And in php that name will be the folder of that file. Example All files are now saving in ""uploads"" folder. I need file save in upload>name>file-here. Any one can help in code so please
handleInputChange(event: any) {
const image = event.target.files[0];
const reader = new FileReader();
if (!image.type.match(/image-*/)) {
this.Toastr.error('Image are not valid.', 'Failed!');
return;
} else {
this.photo = image;
reader.onload = (event1: ProgressEvent) => {
this.url = (<FileReader>event1.target).result;
};
reader.readAsDataURL(event.target.files[0]);
this.selectedFile = event.target.files[0];
this.validateImage = false;
}
}
this.ServiceName.saveNewsData("api_url", this.selectedFile).subscribe((response: any) => {
if (response.status == true) {}})
saveNewsData(url, photo) {
const data = new FormData();
data.append('featuredImage', photo);
return this.http.post(url, data,{ headers: header })
.map(response => response)
.catch(this.handleError);
}
Related
I developed a PHP project, now I am working on connecting it to react native app. However, I tried many codes to upload image to the server nothing works.
Here is my code example,
const uploadImage = async () => {
// Check if any file is selected or not
if (singleFile != null) {
// If file selected then create FormData
const fileToUpload = singleFile;
const data = new FormData();
data.append('file_attachment', fileToUpload);
// Please change file upload URL
fetch(
'http://192.168.8.105/insaf/mobileConnection/upload.php',
{
method: 'post',
body: data,
headers: {
'Content-Type': 'multipart/form-data; ',
},
}
).then((response) => response.json())
.then((responseJson) => {
//Hide Loader
setLoading(false);
console.log(responseJson);
// If server response message same as Data Matched
if (responseJson[0].Message == "Success") {
navigation.replace('ReqPriceList');
} else {
//setErrortext(responseJson.msg);
console.log('Please check');
}
})
.catch((error) => {
//Hide Loader
setLoading(false);
console.error(error);
});
} else {
// If no file selected the show alert
alert('Please Select File first');
}
};
And for the PHP server side (upload.php), here is the code
if(!empty($_FILES['file_attachment']['name']))
{
$target_dir = "../assets/files/request/";
if (!file_exists($target_dir))
{
mkdir($target_dir, 0777);
}
$target_file =
$target_dir . basename($_FILES["file_attachment"]["name"]);
$imageFileType =
strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
// Check if file already exists
if (file_exists($target_file)) {
echo json_encode(
array(
"status" => 0,
"data" => array()
,"msg" => "Sorry, file already exists."
)
);
die();
}
// Check file size
if ($_FILES["file_attachment"]["size"] > 50000000) {
echo json_encode(
array(
"status" => 0,
"data" => array(),
"msg" => "Sorry, your file is too large."
)
);
die();
}
if (
move_uploaded_file(
$_FILES["file_attachment"]["tmp_name"], $target_file
)
) {
echo json_encode(
array(
"status" => 1,
"data" => array(),
"msg" => "The file " .
basename( $_FILES["file_attachment"]["name"]) .
" has been uploaded."));
} else {
echo json_encode(
array(
"status" => 0,
"data" => array(),
"msg" => "Sorry, there was an error uploading your file."
)
);
}
}
I got this code from here https://aboutreact.com/file-uploading-in-react-native/
And I am getting
this error
Can anyone help me?
Any alternative solution will be fine.
Edit:
based on #Sadia Chaudhary code this function works
let uploadImage = async () => {
//Check if any file is selected or not
if (singleFile != null) {
//If file selected then create FormData
const fileToUpload = singleFile;
console.log("fileToUpload is " + fileToUpload);
const uriPart = fileToUpload[0].uri;
const fileExtension = fileToUpload[0].name.split('.')[1];
console.log("fileExtension is " + fileExtension);
const data = new FormData();
//const uriPart = fileToUpload.split('.');
//const fileExtension = uriPart[uriPart.length - 1];
data.append('file_attachment', {
uri: uriPart,
name: `photo.${fileExtension}`,
type: `image/${fileExtension}`
});
let res = await fetch(
'http://myIp/insaf/mobileConnection/uploads.php',
{
method: 'post',
body: data,
headers: {
'Content-Type': 'multipart/form-data; ',
},
}
);
let responseJson = await res.json();
if (responseJson.status == 1) {
alert('Upload Successful');
}
} else {
//if no file selected the show alert
alert('Please Select File first');
}
};
The error has nothing to do with the image upload. You are facing this error because of response.json(). Also, try to convert image like this.
//retrive the file extension of your photo uri
const uriPart = imageSource.split('.');
const fileExtension = uriPart[uriPart.length - 1];
formData.append('photo', {
uri: imageSource,
name: `photo.${fileExtension}`,
type: `image/${fileExtension}`
});
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.
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 trying to do a server-less upload to S3 using DropzoneJS. I'm having issues with the AWS Presigned URL specifically, where it's indicating that the x-amz-acl header is unsigned.
Javascript:
var dz = new Dropzone("div#upload", {
url: "tbd",
paramName: "file", // The name that will be used to transfer the file
maxFilesize: 2, // MB
accept: this.getUploadUrl,
method: 'put',
sending: function(file, xhr) {
var _send = xhr.send;
xhr.setRequestHeader('x-amz-acl', 'public-read');
xhr.send = function() {
_send.call(xhr, file);
}
},
});
dz.on('processing', function(file) {
// change url before sending
this.options.url = file.uploadUrl;
});
function getUploadUrl(file, cb) {
var params = {
fileName: file.name,
fileType: file.type,
};
$.getJSON('signput.php', params).done(function(data) {
var decodedUri = decodeURIComponent(data['signedRequest']);
if (!data.signedRequest) {
return cb('Failed to receive an upload url');
}
console.log(decodedUri);
file.uploadUrl = decodedUri;
cb();
}).fail(function() {
return cb('Failed to receive an upload url');
});
}
PHP (called to get presigned url):
$fileName = $_GET['fileName'];
$s3Client = new Aws\S3\S3Client([
'version' => '2006-03-01',
'region' => 'us-west-2',
'credentials' => [
'key' => '__MY__KEY__',
'secret' => '__MY__SECRET__',
],]);
$cmd = $s3Client->getCommand('PutObject', [
'Bucket' => '__MY__BUCKET__',
'Key' => $fileName
]);
$request = $s3Client->createPresignedRequest($cmd, '+20 minutes');
// Get the actual presigned-url
$url = (string) $request->getUri();
$urlArray['signedRequest'] = $url;
$urlArray = json_encode($urlArray);
echo $urlArray;
I've also tried setting x-amz-acl to public-read in the Dropzone headers and S3 getCommand, but it's not working.
The error I get:
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code>
<Message>There were headers present in the request which were not signed</Message>
<HeadersNotSigned>x-amz-acl</HeadersNotSigned>
</Error>
There was one issue - I needed to move the ACL => 'public-read' from the JS code into the signing request.
The Dropzone sending function turns into this:
sending: function(file, xhr) {
var _send = xhr.send;
xhr.send = function() {
_send.call(xhr, file);
}
}
And the PHP signing requests turns into:
$cmd = $s3Client->getCommand('PutObject', [
'Bucket' => '__MY__BUCKET__',
'Key' => $fileName,
'ACL' => 'public-read'
]);
Thanks to Michael for pointing me in the right direction.
Final code for reference...
Javascript:
var dz = new Dropzone("div#upload", {
url: "tbd",
paramName: "file", // The name that will be used to transfer the file
maxFilesize: 2, // MB
accept: this.getUploadUrl,
method: 'put',
sending: function(file, xhr) {
var _send = xhr.send;
xhr.send = function() {
_send.call(xhr, file);
}
},
});
dz.on('processing', function(file) {
// change url before sending
this.options.url = file.uploadUrl;
});
function getUploadUrl(file, cb) {
var params = {
fileName: file.name,
fileType: file.type,
};
$.getJSON('signput.php', params).done(function(data) {
var decodedUri = decodeURIComponent(data['signedRequest']);
if (!data.signedRequest) {
return cb('Failed to receive an upload url');
}
file.uploadUrl = decodedUri;
cb();
}).fail(function() {
return cb('Failed to receive an upload url');
});
}
PHP:
$fileName = $_GET['fileName'];
$s3Client = new Aws\S3\S3Client([
'version' => '2006-03-01',
'region' => 'us-west-2',
'credentials' => [
'key' => '__MY_KEY__',
'secret' => '__MY_SECRET__,
],]);
$cmd = $s3Client->getCommand('PutObject', [
'Bucket' => '__MY_BUCKET__',
'Key' => $fileName,
'ACL' => 'public-read'
]);
$request = $s3Client->createPresignedRequest($cmd, '+20 minutes');
// Get the actual presigned-url
$url = (string) $request->getUri();
$urlArray['signedRequest'] = $url;
$urlArray = json_encode($urlArray);
echo $urlArray;
We have API which receives images converted in base64 string. Our mobile application consumes too much RAM during the conversion process (to base64), now we need to upload image as multipart. I developed the mobile part but I'm stuck with the PHP API. We switched from volley to Retrofit because volley did not support multipart upload.
What do I need to change in the script that receives the multipart image upload?
<?php
//header('Content-Type : bitmap; charset=utf-8');
//header('Content-Type: application/json');
if (isset($_POST["encoded_string"])) {
//encoded_string -> base64 string sent from mobile phone
$encoded_string = $_POST["encoded_string"];
$image_name = $_POST["image_name"];
$decoded_string = base64_decode($encoded_string);
$path = 'images/' . $image_name;
if (!file_exists('images')) {
mkdir('images', 0777, true);
}
$file = fopen($path, 'wb');
$is_written = fwrite($file, $decoded_string);
fclose($file);
if ($is_written > 0) {
$connection = mysqli_connect('localhost', 'root', '', 'test');
if ($connection) {
$query = "INSERT INTO photos(name,path) values('$image_name','$path');";
$result = mysqli_query($connection, $query);
if ($result) {
echo json_encode(array(
"response" => "Success! Image is succefully uploaded!.",
"result" => "success"
));
} else {
echo json_encode(array(
"response" => "Error! Image is not uploaded.",
"result" => "error"
));
}
mysqli_close($connection);
} else {
echo json_encode(array(
"response" => "Error! No database connection!",
"result" => "error"
));
}
}
} else {
echo json_encode(array(
"response" => "Error! Please insert data!",
"result" => "error"
));
}
?>
Have a look at move_uploaded_file() function of php and the $_FILES array.
Example code plenty on this site.
If you want add multipart upload in backend you should make next changes:
<?php
//header('Content-Type : bitmap; charset=utf-8');
//header('Content-Type: application/json');
if (isset($_POST["encoded_string"])) {
//encoded_string -> base64 string sent from mobile phone
if (!file_exists('images')) {
mkdir('images', 0777, true);
}
$connection = mysqli_connect('localhost', 'root', '', 'test');
if (!$connection) {
echo json_encode(array(
"response" => "Error! No database connection!",
"result" => "error"
));
die;
}
$responses = array();
foreach ($_FILES["pictures"]["error"] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
$tmp_name = $_FILES["pictures"]["tmp_name"][$key];
$image_name = $_FILES["pictures"]["name"][$key];
$path = 'images/' . $image_name;
if (move_uploaded_file($tmp_name, path)) {
$query = "INSERT INTO photos(name,path) values('$image_name','$path');";
$result = mysqli_query($connection, $query);
if ($result) {
$responses[] = array(
"response" => "Success! Image is succefully uploaded!.",
"result" => "success"
);
} else {
$responses[] = array(
"response" => "Error! Image is not uploaded.",
"result" => "error"
);
}
}
} else {
$responses[] = array(
"response" => "Error! Please insert data!",
"result" => "error"
);
}
}
mysqli_close($connection);
echo json_encode(array(
'responses' => $responses
));
}
Also, make shore you use post request with multipart format (it should have header Content-Type: multipart/form-data and bi in right format - https://ru.wikipedia.org/wiki/Multipart/form-data). Hope it help you.