passing php variables with ajax - javascript

I've been trying to get php to rename an image in an S3 bucket. There's three stages
upload image (you can see a previous question I asked to see my
solution to that) I've included the code I used below.
Use ajax to take the name I want for a file (the user ID) and
pass it to a PHP renaming script.
run the renaming script.
Step two is giving me problems. If i hard code the names into the PHP script then it will find the source file and rename it.
However I can't get it to rename the files using variables drawn from the page.
Here's the HTML button code
<input type="file" id="file-chooser" />
<button onclick= "pass()" id="upload-button">Upload to S3</button>
<div id="results"></div>
Here's the JS code
<script type="text/javascript">
var bucket = new AWS.S3({params: {Bucket: 'MY BUCKET'}});
var fileChooser = document.getElementById('file-chooser');
var button = document.getElementById('upload-button');
var results = document.getElementById('results');
button.addEventListener('click', function() {
var file = fileChooser.files[0];
if (file) {
results.innerHTML = '';
var filename = file.name;
var params = {Key: file.name, ContentType: file.type, Body: file};
bucket.upload(params, function (err, data) {
results.innerHTML = err ? 'ERROR!' : 'UPLOADED';
ajax_post();
});
} else {
results.innerHTML = 'Nothing to upload.';
}
}, false);
function pass() {
$.get("test.php");
return false;
}
function ajax_post() {
var ref = new
Firebase("https://MY FIREBASE .firebaseio.com/");
var authData = ref.getAuth();
// Create our XMLHttpRequest object
var fileChooser = document.getElementById('file-chooser');
var file = fileChooser.files[0];
var filename = file.name;
var userID = authData.uid;
var userID = USERS USER ID;
//alert($(this).attr('id'));
$.ajax({
type: "POST",
url: 'test.php',
data: { userID : userID },
data: { filename : filename },
success: function (data) {
alert("success!");
}
};
pass();
}
</script>
Here's the PHP.
<?php
require 'vendor/autoload.php';
use Aws\S3\S3Client;
$sourceBucket = "MY BUCKET";
$sourcename1 = $_POST['filename'];
$targetKeyname = $_POST['userID'];
$targetBucket = "MY BUCKET";
$s3 = S3Client::factory(array(
'key' => "MY KEY",
'secret' => "MY SECRET KEY"
));
$s3->copyObject(array(
'Bucket' => $targetBucket,
'Key' => $targetKeyname,
'CopySource' => "{$sourceBucket}/{$sourcename}",
));
?>
EDITING TO ADD
I've been running test after test. If I hard code the variables into the PHP file it works. If I hard code the variables into the JS script it fails. The ajax is running the php file it's just not passing the variables to it. I've tried with and without the ISSET on the PHP side it just fails to take in the variables each time.
Any ideas?

I suspect this is your issue var userID = USERS USER ID; I'm not sure where that information is coming from. But without seeing the html/js where that is derived from, its difficult to determine the problem.
If its text input with an id of userID, it should be something like:
<input type="text" name="userID" id="userID">
js:
var userID = $("#userID").val();
AJAX Update
merge BOTH data into one object:
data: { userID : userID },
data: { filename : filename },
will become
data: { userID : userID , filename : filename },

I found out what the issue was. It was Firebase. Firebase was returning the values I required however the PHP script was retrieving an error from AWS. I had assumed that the AJAX was failing to pass the value on but I was only half right. the AJAX failed because it didn't have the value at that point. I added in a 3 second delay before the upload occurs and it works fine. Firebase was just slower than the PHP.

Related

C# generating and downloading PDF file not working

I'm trying to generate and then download PDF file from a simple form.
I've got 2 options for users:
1. Generate and download directly after filling the form
2. Generate and download the saved documents.
The first one works perfectly, but the second case has a problem.
I'm using ajax to call the Download action:
function complaintDownload(object) {
var id = object.id;
$.ajax({
type: "POST",
url: '/Lawyers.AppPortal/Statement/Download',
data: { id: id}
});
}
Here's my action:
[HttpPost]
public FileContentResult Download(int id)
{
var statement = Engine.Get<Statement>().FirstOrDefault(a => a.Id == id);
var pdfModel = statement.ToStatementPdfModel();
var path = BLL.PdfGenerator.Generate(pdfModel);
var pdfBytes = System.IO.File.ReadAllBytes(path);
return File(pdfBytes, "Application/pdf", "test.pdf");
}
When I call this action nothing happens.

How do I upload a file using POST in angular?

How do I transmit a pdf file? I have found multiple ways online, but most of them involve a rework of how our current system works, which is far from ideal.
Im not too familiar with angular, but I am trying to upload a file to the server. i am using existing architecture, so the issue isnt as easy as simply rewriting it from the ground up. Spring complains that "The current request is not a multipart request", if i try to send it as a multipart file, but I dont know how to make it one. The file type must be of type Blob. Currently, no error is thrown, but data.content is empty after the data block is transmitted.
Here is what I currently have:
$scope.uploadPDF = function(uploadedPDF) {
var url = 'uploadPDF';
data = {};
data.comments = $scope.worksheet.comments;
data.queryId = $scope.qId;
data.responseId = $scope.responseId;
data.requestTS = new Date().getTime();
data.content = uploadedPDF;
$http.post(url, data);
};
and the function that calls it is this, it pulls in the file, generates a name and adds the name as a property to be handled serverside, does some unaffiliated logic, then calls the above function for transmission:
$scope.addPDF = function() {
var pdfUploads = document.getElementById('file');
if ('files' in pdfUploads)
{
if (pdfUploads.files.length == 0)
{
$scope.setReasonForChange("addPDF");
}else
{
for (var i = 0; i < pdfUploads.files.length; i++)
{
var currentTimeZone = new Date().toLocaleTimeString('en-us',{timeZoneName:'short'}).split(' ')[2];
$scope.militaryTime = $filter('date')(Date.now(), "MM-dd-yyyy_HHmm");
pdfUploads.files[i].generatedFileName = "QID-" + $scope.queryId + "_" + $scope.worksheet.response.PDF_DESCRIPTION + "_" + $scope.militaryTime + currentTimeZone + ".PDF";
}
}
}
var pdfComment = document.getElementById("pdfComment").value;
if (!pdfComment)
{
$scope.setReasonForChange("updatePDF");
} else
{
var blobPDF = new Blob([pdfUploads.files[0]], {type: 'application/pdf'});
$scope.uploadPDF(blobPDF);
}
}
HTML is:
<form name="UploadForm" id="UploadForm" class="details" form-on-change="formChanged()" enctype="multipart/form-data">
<input type="file" multiple size="50" id="file" name="file" ng-disabled="is_readonly"/>
<button ng-click="addPDF()" ng-disabled="is_readonly">Add</button>
</form>
And lastly, serverside is this, where i think data is part of a linkedhashmap, where the values are taken from in the server, and processed:
#ResponseBody
#RequestMapping(value = "/uploadPDF", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseAttachment uploadPDF(#RequestBody Data data, HttpServletRequest request) throws Exception {
User user = (user) request.getSession(false).getAttribute(FieldConstants.USER_SESSION_ATTR);
ResponseAttachment newPDF = responseAttachmentService.addAttachment(data, user.getUserId());
return newPDF;
Currently, it transmits and receives the data, except the place where the file is supposed to be is empty.
I have attempted ng-fileupload, but attaching it to our product is a nightmare, especially considering that its use kinda requires the user to already know how to use angular as it has little documentation... and we have no angular people.
This question may help you.
Basically you can't send files in purely a JSON format. You have to use a multipart form and post it that way. For example:
postFile(file) {
var postData = new FormData();
postData.append('File', file);
var params = {
headers: {
"Content-Type": undefined
}
$http.post(url, data, params).then([...]);
}
You'll need the extra Content-Type param so that it is sent properly.

How to post file with ajax?

Trying to save a file to a db. I am using formData via javascript to append the file and adding this as a post object via ajax. for some reason nothing gets sent.
What am I doing wrong?
HTML
<input type="file" style="display: none;" class="btn btn-primary uploadFile">
script:
$(".saveImage")
.on("click",
function() {
var files = $(".uploadFile");
var data = new FormData();
data = $.OverWatch.worker.uploadFileHandler.addUploadFiles(files, data);
$.OverWatch.worker.postUserData("/Administration/AddUserImage", data, function () {
alert("done");
});
});
Functions above look like:
addUploadFiles: function (files, data) {
$.each(files, function (i, v) {
var file = $(this).data("files");
data.append("file", file);
});
return data;
}
postUserData:
postUserData: function(url, data, callback) {
$.LoadingOverlay("show");
$.ajax({
url: url,
type: 'POST',
data: data,
cache: false,
processData: false,
contentType: false,
dataType: "HTML",
success: function(data) {
if (callback) {
callback(data);
$.LoadingOverlay("hide");
}
},
error: function(event, jqxhr, settings, thrownError) {
//$.helpers.errorHandler($("#fileDialogErrors"), event.responseText);
var h;
$.LoadingOverlay("hide");
}
});
},
backend:
public ActionResult AddUserImage()
{
if (Request.Files.Count != 0)
{
//save
}
return null;
}
edit:
var files = $(".uploadFile");
returns:
Your var file = $(this).data("files"); line of code would be returning undefined (unless you have some other javascript adding a data value, but you cannot add files to data so it in any case it would not be returning a file).
Change your loop to
$.each(files, function (i, v) {
for (i = 0; i < v.files.length; i++) {
var file = v.files[i];
data.append("file", file);
}
});
However, you can simplify this by using var data = new FormData($('form').get(0)); which will serialize all you form controls including file inputs to FormData (refer how to append whole set of model to formdata and obtain it in MVC for more information).
I also recommend you change your method signature to
public ActionResult AddUserImage(IEnumerable<HttpPostedFileBase> files)
and let the DefaultModelBinder do its magic.
you can directly get file from controller when called using Request.Files
//(Request) HttpRequestBase object for the current HTTP request
if (Request.Files.Count > 0)//// Is image is uplaod by browse button
{
var inputStream = Request.Files[0].InputStream;
using (var binaryReader = new BinaryReader(inputStream))
{
var ImageBytes = binaryReader .ReadBytes(Request.Files[0].ContentLength); // same as you can get multiple file also
}
var fileExtension = Path.GetExtension(Request.Files[0].FileName);
}
thanks.
I haven't done it with jQuery but just learned how to do it myself yesterday using plain old javascript... the following worked for me. If you want to stick with jquery maybe you can translate the functions to what you need:
var formElement = document.querySelector("form");
var payload = new FormData(formElement);
function onStateChange(ev) {
// Check if the request is finished
if (ev.target.readyState == 4) {
editor.busy(false);
if (ev.target.status == '200') {
// Save was successful, notify the user with a flash
} else {
// Save failed, notify the user with a flash
}
}
};
xhr = new XMLHttpRequest();
xhr.addEventListener('readystatechange', onStateChange);
xhr.open('POST', '/posts');
xhr.send(payload);
Maybe see if using the above code works for you (it just targets a form that you have on the same page), and then you can troubleshoot whether it's your script that's the problem or a backend / communication problem.

Sending a file and some string value in single post request using angular controller

I am trying to upload an image to the server along with that I am sending a string value through $ upload post method. Some how I am able to process the requested file through the $upload method. I dont know how to access the string data that I send through this post request.Here is my controller code
$scope.string1="abcd";
createFile = $scope.files.slice(0);
console.log(createFile);
console.log("upload function");
if (createFile) { // console.log(file.name);
$scope.upload = $upload.upload({
url: '/uploadResortsImage', //upload.php script, node.js route, or servlet url
method: 'POST',
data: {
myObj: $scope.myModelObj,
$scope.dataone:$scope.string1,
},
file: createFile, // or list of files ($files) for html5 only
// fileName: this.name +'.pdf', //or ['1.jpg', '2.jpg', ...] // to modify the name of the file(s)
})
My appliaction stack is meanjs and Here goes my server code.
exports.upload = function (req, res) {
console.log("upload function");
console.log(req);
var filename = '',
target_path = '';
console.log(req.files);
var form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
console.log(files.file);
var tmp_path = files.file.path;
var tmp_path_string = String(tmp_path);
console.log(tmp_path_string);
filename = files.file.name;
var dir = "./public/uploads";
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}
var dir1 = dir + '/' + resortid;
if (!fs.existsSync(dir1)) {
fs.mkdirSync(dir1);
}
var dest_path = dir1 + "/";
target_path = dest_path + filename;
console.log(dest_path);
console.log(filename);
console.log(target_path);
var target_path_string = String(target_path);
fs.rename(tmp_path_string, target_path_string, function (err) {
if (err) {
throw err;
console.log("fail");
console.log(err);
} else {
console.log("successful");
done(err, resort);
}
});
});
}
I think this what you need
data: {
myObj: $scope.myModelObj,
myObjB: $scope.string1,
},
Then on the server side, you would just access that myObjB property or whatever you decide to call it in the incoming form values collection depending on what your are using server side. Using $scope.dataone as a property name in your data object doesn't make sense as that's a scope property from elsewhere in your AngularJS code, stick to simple property names.
I was using formidabble plug in the node application.My code goes like this and I am able to access the send data objects in the server side.
form.parse(req, function (err, fields, files) {
var data_received= fields.myObjB;
}
Thanks.

How to send values from jQuery-AJAX function to PHP file and access those values in PHP file?

I've written a jQuery-AJAX function as follows :
$('#request_form').submit(function(e) {
var form = $(this);
var stud_id = $('#stud_id').val();
var reg_date = $('#reg_date').val();
var formdata = false;
var fileInput = $("#receipt_image")[0];
/*I want to pass values of below variables to the PHP file.*/
var ImgSizeInBytes = fileInput.files[0].size;
var filename = $('input[type=file]').val().split('\\').pop();
var customer_id = $('#customer_id').val();
/*These values need to send to PHP file and access there */
if(window.FormData) {
formdata = new FormData(form[0]);
}
var formAction = form.attr('action');
$.ajax({
url : 'student_request.php',
type : 'POST',
cache : false,
data : formdata ? formdata : form.serialize(),
contentType : false,
processData : false,
success: function(response) {
var responseObject = $.parseJSON(response);
if(responseObject.error_message) {
if ($(".alert-dismissible")[0]) {
$('.alert-dismissible').remove();
}
var htmlString = "<div class='alert alert-danger alert-dismissible' role='alert'><button type='button' class='close' data-dismiss='alert' aria-hidden='true'>×</button>"+responseObject.error_message+"</div>";
$(htmlString).insertBefore('div.modal-body #request_form');
} else {
alert("Student successfully registered...!!!");
}
}
});
e.preventDefault();
});
Now I'm able to access the values filled in by user on a form by means of $_POST array in PHP file. But I also want to pass the values I put in comment in my code above to the PHP file.
The values/parameters which I want to send are not part of a form fields. I've manipulated the values of these variables. So they can't come in $_POST array.
My issue is how should I send these values to PHP file and how should I access these values in PHP file?
You should change this: formdata ? formdata : form.serialize()
Store this in a variable and concatenate the values you want to send.
For Example:
var pars = formdata ? formdata : form.serialize();
pars += "&myField1=myValue1&myField2=myValue2"
As #chris said, all you need to do is to concatenate your own hidden variables to post variables. As I see, you are confused about how to use those extra variables in your php file, here's simple example:
var params = formdata ? formdata : form.serialize();
params += "param1=myExtraVar1&param2=myExtraVar2";
So now you have all variables ready to be sent to your php file, modify your data parameter in ajax call like this:
...data: params,
So far, so good. Let's see the other side (PHP)
<?php
// get the variables you want to treat.
$param1 = $_POST['param1']; // now you have access to this variable from ajax call
// Notice you can display all variables you have in superglobal variable POST
// by dumping it using either var_dump($_POST) or print_r($_POST)
Hope this helps understand better the process, and feel free to comment and I'll get back to you
Another thing I captured and I'd like to share with you is that you can use datatype to JSON instead of casting your returned response, so you can put this code anywhere inside your ajax call:
dataType: "json", // if you put this in last line, omit the comma, otherwise leave as it is

Categories