Upload files with Angular for PHP - javascript

I'm trying to upload a file using Angular (currently Angular 4).
But I'm unable to send it correctly. The best I can do is sending the file as a raw content (available in $_POST as some binary mess like this: )
ëPNG\r\n
\x1A\n
\x00\x00\x00\rIHDR\x00\x00\x00©\x00\x00\x008\x08\x06\x00\x00\x00Nâ2\x1F\x00\x00\n
óiCCPICC
What I want is the file to be uploaded and available in $_FILES variable in PHP.
Currently, I'm using this code in Angular
let picture = event.target.files[0];
let content = new FormData();
content.append('picture', picture, picture.name);
let headers = new Headers({'Accept': 'application/json',
'X-AUTH-TOKEN': this.user.token,
'Content-Type': picture.type});
let options = new RequestOptions({headers: headers});
this.http.post(Config.API_URL + `/user/profile/update/`, value, options).subscribe(response => {
console.log(response);
});
Currently, PHP code is just a var_dump($_FILES);
I think my problem may be related to the way Angular transforms the request.
I know there war a transformRequest option in AngularJS but I can't find how it works with Angular 4.
Do you have any suggestion on how I can make this work?
Thanks.

Related

How to upload file in NodeJs to PocketBase

I'm working on a project where I need to upload many PDF files to a PocketBase collection.
I have all the files on my computer and I'd like to upload them using nodejs and the PocketBase JavaScript SDK. PocketBase expects me to send the file as a [file object], which is not possible in nodejs.
Ideally the code would look something like that:
const fileObject = loadFile(pathToFile);
const entry = {
nameField: "some-field",
fileField: fileObject
}
await pb.collection("my-collection").create(entry)
I didn't find any bits of code that could help creating a loadFile function.
You are supposed to send your form as multipart/form-data when uploading files to pocketbase.
Try:
const res = fetch(
"http://127.0.0.1:8090/api/collections/my-collection/records",
{
method: "POST",
headers: {
"Content-Type": "multipart/form-data",
},
body: myFormWhichHasFiles,
}
)
Also, make sure you don't use JSON.stringify on your form when using multipart/form data.
Pro tip: if you leave out 'Content-type', it should default to multipart/form-data.

Does there exist a 'good-practice' way to send files without relying on FormData?

I'm currently working on an app with a React Native front-end and Node.js/Express backend. I am perfectly able to upload files using FormData with Content-Type multipart/form-data. The problem I have is that when using FormData, any other data that you wish to send in the body of the request is necessarily converted to a string. This isn't the case when one simply sends a JS object as the body of the request (as long you parse it on the backend of course). I wish to know if there is a good-practice way to send a file/files alongside JSON in a request, without losing the typings of said JSON?
Thanks
Add your data as JSON in a field of the FormData:
const data = {
foo: ["bar", 1]
};
const file = new File(["some content"], "myfile.txt");
const formdata = new FormData();
formdata.append("file", file);
// Send as JSON
formdata.append("data", JSON.stringify(data));
const req = new Request("./", { method: "POST", body: formdata });
// simulate server side getting the response
req.formData().then( (fd) => {
const received_file = fd.get("file");
// parse JSON
const received_data = JSON.parse(fd.get("data"));
console.log({ received_file, received_data });
});
When you insist on sending the image along with other data inside the JSON, then AFAIK your only option is to convert the image to some data type which can be transmitted via JSON.
The most obvious choice would be a string, and what is usually used here is the base64 encoding. It is, however, not very efficient and can cause lag.
What is sometimes done to stay within the JSON domain but still being able to upload images is to create two endpoints. One for the JSON data. One for the image upload in a binary format.

Reactjs | How to make boundary static when content type is multipart/form-data

We are facing one issue while we are making file upload post call using React-JS, in dev-tools under form data we are getting some browser generated boundary.
------WebKitFormBoundarypSTl3xdAHAJgTN8A
And because of this random boundary we are getting issue while we are making call to a third party api.
Is there any way to make this boundary some fixed value. Something like this :
----somefixedvalue.
Here is the js code:
function doupload() {
let data = document.getElementById("file").files[0];
console.log('doupload',data);
let formData = new FormData();
formData.append("file", data);
fetch('http://localhost:8081/upload/multipart',
{
method:'POST',
body: formData,
headers: {
'Content-Type': 'multipart/form-data; boundary=----somefixedboundary'
}
}).then(res => {
for(const header of res.headers){
console.log(`resHeaderName: ${header[0]}, Value:${header[1]}`);
}
});
alert('your file has been uploaded');
location.reload();
};
can someone help me to solve this? I'm quite confused here as i have given content type along with some static boundary but no luck.
You can convert a file to the binary string and prepare the body by yourself instead of using FormData as it shown in this answer.
But keep in mind that if this ----somefixedvalue substring appears in the file it will be considered a boundary causing body parsing error on receiver side. In case of FormData, browser should take care of it and prevent this.

How to send file details to back end using angularjs?

Hi I am developing web application in angularjs. I am developing file upload module. I have below array with file details.
//below code to get array of files
$scope.showPicker=function()
{
var client = filestack.init('AGeDIRvVZTRWgtmFbfGuZz');
client.pick({
}).then(function (result) {
arrMakes.push(result.filesUploaded);
});
}
In the above image i shown my array. I have three files.
Below is my angular code to send details to api.
var files = new FormData();
angular.forEach(arrMakes, function (value, index) {
console.log(value,index);
files.append(index, value);
files.append('data', angular.toJson(index).replace(/['"]+/g, ''));
});
return $http.post(this.uploadUrl, files, {
transformRequest: angular.identity,
headers: {
'Content-Type': undefined,
}
})
The problem is i am not receiving file in server side. Below line gives me 0 files in server.
System.Web.HttpFileCollection hfc = System.Web.HttpContext.Current.Request.Files;
May i know am i sending correct data to server? Can someone help me to fix this? Any help would be greatly appreciated. Thank you.
You are not uploading any files to the server, only strings.
You can't append objects to a FormData. appart from Blob & File objects See what will happen:
fd = new FormData
fd.append(2, {foo: 'bar'})
fd.append('data', 5)
new Response(fd).text().then(console.log)
// you get [object Object]
Why do you stringify the index in "data"? It will be casted to string automatically. And what is there that you have to replace?
If i where you i would just simple send the hole arrMakes to the server and download all the files from the url on the backend, otherwise the client has to download and then upload them to the server and wasting bandwidth and time.
beside, you don't need angulars forEach loop, arrays has that method built in
arrMakes.forEach(function (value, index) {
...
})
You won't even have to use any loop if you just pass the arrMarks to the server

AngularJs File Upload without FormData

I've made a simple drag and drop directive for file uploading, but my main concern is that i need to have IE8/9 support, so taking in account that FormData is not supported, how can i do a multiple file upload without using the FormData object?
Thanks in advance.
EDIT:
What i'm trying do do is this:
$scope.uploadFile = function () {
var upload = $http.post('awesomeFileThatWantsMultipleFilesUploaded.php',
angular.element(document.getElementsByClassName('droppable')).scope().files,
{withCredentials: true,
headers: {'Content-Type': undefined },
transformRequest: angular.identity})
.success(function (response) {
});
return upload;
}
But the problem is that when the browser doesn't have support for FormData, i initialize the files variable as array, and then i push each file to the variable. If the file is FormData, this works.
Don't make this by hand. Is rather messy and you will always have problems. You can use a polyfill for formdata, like moxie, for angular I use angular-file-upload there is even a way to upload to S3 from the browser (here)
If you want to do it by hand, check the code in those repositories and find some ideas

Categories

Resources