I'm currently creating an image hosting script and so far so good. I've used several plugins to create the local uploading process with drag & drog + AJAX which works totally fine. Now I've moved to the part where I need to create the remote uploading process with jQuery AJAX and a PHP script to handle the whole thing.
How it's gonna work
My thought are like this: There is a big box in the middle of the page that accepts the URLs to be remote uploaded. Once valid URL(s) are passed into the text area, they will be immediately sent to the server side script via jQuery AJAX. It's bound with a keyup event.
This is how it looks like: http://i.imgur.com/NhkLKii.png.
The "HERE COME THE URLS" part is already a text area - So that part's already done.
Where I need help
The issue with this whole situation is: Once there are valid URLs pasted into the text area, those must be immediately be converted to some sort of box which also includes an uploading progress. Something that looks like this (copied from the local uploading part): http://i.imgur.com/q7RyDmb.png
It was easy implement the progress indicator for the local uploading, since it was a feature offered by the plugin I've used, but I don't know how to indicate the progress of remote uploading, which is totally being made from scratch.
So this is how I've imagined the logic to flow:
User pastes some URLs into the text area
There is a client-side check to validate the pasted URLs
Validated URLs are send to upload.php on keyup (?)
URLs are being processed
While the upload goes on, we show the users the progress in the knob (?)
PHP script finishes the process and returns back the uploaded URLs
I update the page in the AJAX success callback to display the uploaded files
So, the two process flows marked with (?) are unclear to me - I don't know how to achieve those...
What I have tried
Well, I didn't just come here and ask you to do everything for me, but I've come across a dead end and I don't know how to continue. What I've done so far is collect the URLs from the text area, and if there are multiple URLs separated by a line break (\n), I simply use split to get an array of pasted text and then use another function inside the loop to validate if they are URLs. If there is no line break detected inside the text area value, then I simply check the one line that was provided. On each case, I send the whole text area to the PHP script, because I don't know how to get rid of the invalid URLs in jQuery. I've created a function called debug() in PHP which stores anything into a debug.log file and this is what I'm getting (in one try) when I paste something into the text area:
https://www.google.com/https://www.google.com/
I paste https://www.google.com/ once in the text area, but it gets logged twice in the PHP side and I can't determine why.
This is how my jQuery looks like:
// Remote upload
var char_start = 10;
var index = 0;
var urls = $('.remote-area');
var val_ary = [];
urls.keyup(function(){
if (urls.val().length >= char_start)
{
var has_lbrs = /\r|\n/i.test(urls.val());
val_ary = urls.val().split('\n');
if (has_lbrs)
{
for (var i = 0; i < val_ary.length; i++)
{
if (!validate_url(val_ary[i]))
{
val_ary.splice(i, 1);
continue;
}
}
$.ajax({
type: 'POST',
url: 'upload.php',
data: {
upload_type: 'remote', // Used to determine the upload type in PHP
urls: val_ary, // Sending the whole array here
},
});
}
else
{
if (!validate_url(urls.val()))
{
// Display an error here
return;
}
$.ajax({
type: 'POST',
url: 'upload.php',
data: {
upload_type: 'remote', // Used to determine the upload type in PHP
urls: urls.val(), // Sending what's in the text area
},
});
}
}
});
The questions
So the final questions are:
How do I send my information correctly to the PHP script, only valid URLs and have them kind of "process-able" in my PHP script.
How do I indicate the progress of the upload?
If I was somewhere unclear during my question, please let me know, I'll try to reexplain.
Thank you.
Updates
09/12/2013
I think I have managed to solve the double-sending issue where my AJAX would send the same information twice to the PHP script. What I did was code in a delay anonymous function that sends the text area content to the PHP script after an user stops typing for 2 seconds. Once the user stops typing again, the timer resets and a new AJAX request will be made. So, I'm assuming that this issue has been solved. I'll come back to it if anything strange occurs.
Now I'm still left with the progress indicators part. I'd appreciate your thoughts on that one.
My new code: http://pastebin.com/SaFSLeE9
What you're looking for in terms of communicating progress back and forth is "pushing". That refers to the technique of server sending data to the client, rather than the other way around, which is the standard HTTP way of doing things.
You've got plenty of options available, as described in the explanatory Wikipedia article, though perhaps more relevant to this topic would be Comet. What happens is you trigger and $.ajax call just like the one you have now, but you set a very long timeout. That essentially gives the server a "channel" to send data back to the page whenever it's available.
So what you need is a .php on the server that is capable of handling long polling and will send data back to the page as the upload progress changes (probably in array form for multiple uploads). This article should get you started with some jQuery code. Just remember that this request doesn't go to upload.php. This request goes to a different script that deals solely with upload percentages and only returns data when that is available, it doesn't return immediately as all others scripts - the Ajax will happily wait for the data.
Also, don't separate your code like that with has_lbrs. One line or many are not distinct cases, one line is just an edge case of many lines. You're duplicating the code unnecessarily. What does the else case do that would break in the general case? Further, the "error handling" in the else case is misleading. The only error reporting you do is if there is only one line and it's wrong. What if you have two lines and they're both wrong? Your code will happily send an empty array to upload.php.
This is why I think you shouldn't separate your code like that, because then you'll split logic and not even notice it.
In my opinoin, the best way is to call your cURL script with ajax and use it to upload your files on remote server. You need ajax.js, curl.php, index.php (whatever name you want) on your app server. And image.php, class.image.php (whatever name you want) on your remote server.
Steps that I did for my app
1) I am going to upload an image from my index.php file. It will call curl.php file using ajax.js and the cURL file will check file's extension and all (for your app's security, make sure what you want to allow users to upload).
2) Now the curl file will upload the file to your pre defined temporary folder with the default file name.
3) Now if move_uploaded_file function (which I used in my script) run successfully, you can call your cURL function to send your data as post on your remote server, where image file will receive posts and will process further. You can keep your class in image.php or you can create two PHP files on your remote server, as you want.
4) Now in your class file, you should check file once again that it is image file (and whatever you want to allow) or not for better security. If file is good, process to rename it and add file into folder if you want to.
5) Add file's new name and folder name into your database by using remote database connection. So, cURL will show you result on the same page.
Now, why cURL? I prefer cURL because, you can add secret key or API for your communication to make it more secure, with if else conditions. Your remote server file which is going to receive all posts, will check if API == 'yourKey' then will process other wise it wont process and nobody will be able to send images on your server with bots and all.
I don't know that my answer is going to help you or not, probably my method is lengthy or not good for your app, but try to Google about cURL and you will understand what I am trying to say. Hope you like it and understood it. If any doubt, you can ask me any time.
Related
I am new to web development and I am trying to build my first website.
I am having some troubles because web development is dependant on several programming languages like PHP and JS, and the most difficult part for me is to communicate between these languages.
For example, I am trying to create a function that compresses a folder and generate a download link to that new archive, this can be easily done by PHP. However, when the user clicks the zip button, I also wish to display a pop-up window that tells the user to wait while the folder is being compressed, and when the compression is done I want to change the text on that pop-up and display the download link, and this, of course, requires JS.
I've tried many solutions but none of them seemed perfect for me, and I feel like that these solutions are quick and dirty, which I don't want.
If there is a secret I do not know, please tell me about so I can finally work with these languages as if they are a single language.
Also, if you can help me with my current problem, I would be extra grateful.
I just want to know how to construct a form that can call the JS function that displays the pop-up, then calls the PHP Zip_Folder function, and once the PHP function is done, I want to display the download link on the pop-up window.
This is my form code: (It only calls the javascript function that displays the pop-up)
<input type = 'button' onclick = 'Show_PopUP(\"Folder_to_zip\")' value = 'Download Folder'>
And this is the Show_PopUP function code:
function Show_PopUP(folder) {
var e = document.getElementById('Folder_Download_PopUp');
if(e.style.display == 'block')
e.style.display = 'none';
else {
e.style.display = 'block';}}
I already have the PHP function that compresses and generate a download link for the archive, so what I need now is a way to call it after the pop-up is displayed, and a way to print the download link on the pop-up once the function is done.
This might not be the best approach since I am a beginner, so if you have suggestions on how to get my task done without this complexity, I would be very happy.
Sorry if my question is too long, and thanks in advance for your help.
What you need to do is use these things called XHRs, or XMLHttpRequest (Google it), from within JavaScript to php, which basically is kind of like an invisible browser going to the php page behind the scenes and "loading" whatever the php page gives back, only this is all happening within JavaScript itself, so you can read that this "invisible page" loaded, which is from php, and do stuff with that, without actually refreshing the page. This process is known as AJAX (look it up)
What you can do is, when you set up this "invisible page", you can also send certain kinds of information along with it that the php page can read, and when it's done the php page can echo something back to the invisible page, which can then be read with JavaScript. This easy you can communicate between php and JavaScript, by sending certain values, in JavaScript, along with this invisible page, and waiting for php to echo something back to it, then reading that with JavaScript
So how do we actually do this?
First on the JavaScript side, we need to make this "invisible page", which is really not technically a page, it just does the sane thing as what is done to display any other web page, which is technically called a "request" since it's like asking the server for some data, it's basically "requesting" it, then when the server echoes something back, that's called he "response" to what was requested
So to make this new request in JavaScript we can do the following
var asking= new XMLHttpRequest ()
now that it as if an invisible page was created, but not yet navigated to anything, but we have to now metaphorically "enter in the URL" to this invisible page (without actually "navigating" to it yet) to do that we do
asking.open("GET", "pathToPHPpage.php?hi=there")
So the first part is called "GET" because we want to simply get a response back, without actually sending anything (if we were sending a file though, we would instead use "POST" then put the file date in the next step), then we enter in the URL to the php page that you want to get. If it's the same as the JavaScript page just put location.href instead, but it's important to add at least something to the end of the URL, notice the "?hi=there", you can call it anything, but it's important to have a question mark immediately following the .php page, then the name of something (in this case"hi") followed by it's value (in this case "there"), because the php page is able to read that, and give a different response back depending on what it says
Ok so now we have to actually "send" that request to the server, which is like metaphorically "navigating" to the URL on the invisible page, to do that
asking.send()
(And if you put "POST" before, you can add the date you want to send in between the parenthesis, usually in the form of a string but it can be different depending on the data, look it up for more reference)
Now, before we continue in the JS side, let's quickly switch over to PHP (doesn't have to be in this order though) to see what happened
We need to listen for any "requests" on the php page, that contain the name "hi" (since that's what we at the end of the URL before), to do that, around the top of PHP (technically anywhere in php though) we do
$isHi = $_GET["hi"];
if(isset ($isHi)) {
//Do some php code
echo "hi back!".$isHi;
}
Basically we just looked for the *hi" name in our "GET" request that was sent to PHP, we checked if it is "set", meaning not nulll, then we echoed some message back to JS, now let's listen for that message on the JavaScript side
Back to JS, after the .send line (or before), we need to listen for when the page echoes back.
To do that we check if it successfully loaded, because sometimes there can be errors, so let's do
asking.onreadstatechange= function () {
if(asking.readyState == 4 && asking.status==200) {
alert(asking.responseText)
} else alert("ooh something happened")
}
Now we have access to the response the php code gave us
You can extend this to other forms of communication, let me know if you have any questions
I have an AJAX call that is running a long PHP script where it has 20 different results, I would like to show when each step in the script is done.
Like so 1/20 done, 2/20 done, 3/20 done.
Latest 29-12-2015 03:17.
I tried to create the JSON file as so (jsonFileName_uniqueTimeStampHere.json) by PHP, but the time taken to create the file with PHP, result in a 404 file not found error!
Because when the AJAX call is running it comes to the progress call before the file has been created, I know I can't create the file with JavaScript but is there anyway to create.
The file before the success callback from jQuery AJAX?
What would be the best way to show progress information while AJAX call is running.
The way I have it now, I have a JSON file saved on the server that gets updated with the latest state that has completed, but if multiple users is running the same script the JSON file with the state gets overwritten.
Should I save the state of each progress in DB and then receive it with multiple calls to a PHP method that get state that has been completed?
Should I keep using the current method I use and add a userID to the JSON file so it is unique on each call to the file?
How should I go about doing it the same way as Seositecheckup?
What is the best way to make a progress with AJAX and PHP?
Please tell me if you need any more information.
I have looked around and don't feel like the info or half of info, there is to find online has been enough to do this myself.
I would like to use jQuery AJAX and not XMLHttpRequest, I'm looking for something similar to seositecheckup.com, when you scan a page you can see the state update on each completed function in the console and is done with different AJAX calls. How is that possible?
Should I forget about using jQuery and keep focus on plain JavaScript instead?
Right now I have a setup with jQuery that works the problem is, that I use a JSON file to get the result from and it gets overwritten when multiple users request the same script, is it possible to store the state in db instead and receive it from there with some unique identifier?
In the future I would like to make it possible to put the script into a queue that could be run and when the script ends it should send an e-mail to the user.
The HTTP way of handling requests that may take a long time is for requests to return a 202 and the body of the response should contain the URL where the user can query for the result.
#Request
POST /some/entitities
...
#Response
HTTP/1.0 202 Accepted
/jobs/{jobId}
The user can then poll /jobs/{jobId} which can return a number to represent progress. Do you have to use this? No, but if you do, others developers can immediately recognize what is going on.
Even if you don't use the approach I recommend, you will also have to keep track of job progress in your database and have a separate AJAX call to find out the current progress.
I was wondering if there was any way to create something like a txt file in Ajax. I'm using this to save logs created by the user on my site, this is the link if its helpful: site. If this cannot be done with ajax can it be done with cookies? Or would the log be to big for cookies? Thanks(sorry if this is a duplicate, some I looked around and everything was about loading/reading from a file).
AJAX is just making asynchronus HTTP calls on the browser.
So, can you create a file just making an ajax call? No. You would need to setup somekind of script on the server that will handle the file creation and writing and call that script with AJAX.
The short answer is - no. You can not do this DIRECTLY with AJAX.
The longer answer is - what you are looking for should be done using a database and SQL. Not that PHP couldn't do it directly - but a good database is better able to handle this problem.
AJAX is mainly used to just send and receive messages, files, etc... It isn't for storing anything. With that being said, the steps would be to have a small PHP script that just reads and writes to a database and make that database be a log file. So your SQL database (I'd just call it log) would have two entries. These are the date the log entry went into it and the entry itself. You could also throw in last_accessed if you want or other fields you think you might need. Your PHP script, in its simplest form, would open the database and, depending upon whether you send it a "GET" or "PUT" command it would read from or write to the log file. If it writes to the log file, it sends back an ACK or NAK (meaning everything is ok or the program had a problem). If it is reading from the log file, you supply how many lines you want to read and the PHP script either sends back the lines or a NAK again to signify something went wrong. You can also replace the simple NAK with the actual error if you want but then your customers are seeing the error. Better to have just a generic "There has been a problem, we have contacted our system people and the site should be back up shortly" kind of message. Save the actual errors for you to see via e-mail.
That's it. You should be able to write this in about ten to fifteen minutes and have your log file readily available to you in no time.
I am building a module for SugarCRM that will be used by many people. Early on I ran into a probelm when saving data with PHP losing part of the POST, I learned that the problem was caused by the PHP INI Setting for max_input_vars
Once I increased the value set for max_input_vars, everything worked perfect again.
I was able to set the max_input_vars value with an .htaccess file. I have ready that you cannot set this value with the PHP function ini_set()
My major concern is this module will be used on many different servers as it will be used by many people.
I need to code a solution that will require the user to do nothing and still have my module continue to function correctly.
On another post a user had recommended that I change my HTML Form which already saved this data using a jQuery AJAX POST to my backend PHP script.
He says that I should change it to save the data by s ending a JSON object to my PHP backend script instead of the large number of POST Vars.
Does anyone else see this as a good solution?
Here is my current frontend code that handles the SAVE now....
function ajaxSaveTasks(){
window.unsavedChanges = false;
// Display a message to the user that we are Saving
ajaxStatus.showStatus('Saving Task Changes');
var url = "index.php?module=apoll_Web_Projects"; // the script where you handle the form post.
//SUGAR.ajaxUI.showLoadingPanel();
jQuery('#project_tasks').showLoading(showLoadingSettings);
$.ajax({
type: "POST",
url: url,
data: $("#editTasksForm").serialize(), // serializes the form's elements.
success: function(data)
{
//alert(data); // show server response
//SUGAR.ajaxUI.hideLoadingPanel();
hideTaskUnSavedChangesHeaderBar()
jQuery('#project_tasks').hideLoading();
}
});
ajaxStatus.hideStatus();
};
The other user mentions that if this code is modified to POST my FORM using JSON instead that I can get around the max_input_vars issue altogether. If I understand correctly, he is saying that instead of my 1,000+ Form POST variables being sent, it will send it as 1 variable which holds a huge giant JSON string instead...does that sound right?
If this sounds like it could be a good solution, then could someone show me how I might achieve this?
My FORM is a page for Mass Adding and Editing Project Task Database records, so it can be very large and have hundreds of Task records to update in the database.
In the code above you can see that it simply runs $("#editTasksForm").serialize() to get all the Form fields.
This might not even be an AngularJS question and could just be an AJAX question. I'm new to the "developer" side of the frontend so bear with me.
When making an AJAX call to fetch JSON data, where does the logic behind what data is returned and viewed fall? In my mind, there would be a couple of possibilities and I want to understand which is the proper choice and why.
Let's use an example of searching and playing a Youtube video.
The logic could fall to the backend (controller), where the JSON is rendered based on some logic to give you a JSON file with exactly the right data. i.e. you search "cat videos" and when making an AJAX call, the JSON file you pull has been rendered to be only cat videos.
The opposite end would be that the Angular controller has the logic. This would imply that all data is called (cat videos along with everything else... music videos, funny videos, tutorials, and so on) and then sorted through on the client side. This, to me anyway, would be more inefficient / slow for the client, so doesn't seem to make sense. I suppose still might do some filtering of the data on the client side though. So, maybe a search for "cat videos" wouldn't return ALL videos, but definitely all cat videos and any filtering based on, say, # of views, video length, and so on would be done on the client side (vs. calling the database again for a "new" set of videos).
Not sure if this is accurate, but could you have logic in your factory to return only a portion of the data? However, I believe the entire JSON file would need to be rendered, but only portions would be returned. I guess depending on where the JSON file renders (i.e. backend or frontend) this could be similar to either option #1 or #2.
Or maybe I'm misunderstanding things entirely and the way this works is entirely different!
I'm basically looking to figure out how the scenarios of 1. user searches a term and results are shown, 2. user clicks a search result and now more detailed data of the result is on it's own page. And how this ends up working out. I'm looking for help with AngularJS, but I think this ultimately an AJAX question (single page app or not) more than anything.
There's a few critical concepts you may be confused about.
First. JSON is not a file, it's a format, more simply, a type of string. It's really good for collapsing arrays and storing address-value pairs, so a lot of data flies around in that format. Strictly speaking, they are JSON objects, but they're a lot like strings and arrays. It looks like this, if I remember correctly:
{ "name" : "john doe", "pet" : "dog", "hobby" : "parasailing" }
Second, AJAX is a request to the server, made from the client (the browser) after the original page has loaded. That is, you type in 'youtube.com' and the youtube server receives the request and sends a big pile of HTML back to your browser.
You watch your video, make a rating, and the browser doesn't reload the page but instead sends a separate request back to the youtube server with your rating. There's a parameter in the request that says "send it to ratingspage.php". This request is AJAX.
Now, the logic happens (server-side). ratingspage.php receives your request. It contacts the databases, updates or fails or whatever, and sends back a response to your browser. This response may be in JSON format.
Finally, your browser parses that response and updates the DOM (HTML document) as appropriate.
At this point, it's worth noting that if the logic happened on the client-side (browser), the user could see it - this is a security problem! So, sensitive operations should be carried out on the server side, where you can test and sanitize the request data.
In summary:
AJAX is separate from the initial load event.
Information sent is gathered from the client browser
Logic happens server-side
Logic can use whatever language the server understands (PHP, Java, Ruby, etc.)
Information is returned to the browser
Information sent and received may use JSON format
Everything client-side happens in Javascript
Here's a bare-bones ajax request (done in Javascript) with comments. This has no exception handling, state checking, or anything so don't use it! But it gives you the basic idea.
// Make a new request
var req = new XMLHttpRequest(); }
// Requests will have various states depending on whether they're processing,
// finished, error, etc. We'll assume everything went OK.
// We need to establish a handler before the request
// is sent so it knows what to do.
req.onreadystatechange = function() {
// Here's what the server sent back to the browser
alert(req.responseText);
}
// Using the GET method, set up some parameters
req.open("GET", "somelogicpage.php?blah=blee&bloo=bar", true);
// Send the request
req.send(null);
Server-side, somelogicpage.php may look like:
<?php
if ($_GET['blah'] != 'blee']) {
// This is the response text!
echo "Sorry, you need to blee when you blah.";
}
else {
// (or this)
echo "I'm ecstatic to report nothing is wrong!";
}
?>
Your alert(req.responseText) from the handler function in the previous Javascript will say whatever the PHP has dumped out.
So yes, you can use whatever portion of the request you like, and return whatever you like. Javascript kicks bleep.