I am using jquery upload for chunked uploads. Creating a new file and first chunk in my php back-end goes fine, but for the rest chunks I need a file-ID to tell my php script where to append file data.
So my problem is I don't know a way to read the response (ie. file-id) from ajax with jquery upload and edit the post data, in this case add the file id to the requests after the first chunk. The responses seem to behave mysterically.
I console log in my progress-callback console.log(data) and I get a buch of stuff. I can log ie. console.log(data._progress.field) but cannot do this for data._response.file-id as console says undefined. But when i console log the whole data I can clearly see a _response -object inside data. but when I specifically try to log that I get Object { } so it seems to be empty, but when i click it I see jqXHR-object and result-object that has the file-id I want to put to post requests for the rest chunks.
TL,DR:
I can console.log whole data in callback and see the result ie. file-id, but when I try to log data.result.file-id, console says "undefined".
Some fields I can log but some I can't Ie. data._progress.total logs just fine but data._result doesn't.
I need a field from response and change the post parameters for the next requests of chunked file upload.
What on earth I am missing here?
EDIT:
I have found a back-end solution to my problem and I didn't need jQuery/ajax request response things I tried to use. This was proprietary works so sorry I can't post my code.
Related
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'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.
Recently I started facing issue with one of my scripts that loads a json response from the server. I am using jquery.ajax() to make an ajax call. The code snippet is so -
var request = $.ajax({
url: "script.jsp",
type: "POST",
dataType: "json",
success: function(response) {
console.log(response);
},
error: function(response, error) {
console.log(response, error);
}
});
As I mentioned this script worked as recent as yesterday. I have not made any changes to either the server-side code or the front-end code. The json response is a bit large ~1 MB in size. But I validated the json output using -
python -mjson.tool < output.json
It prints out properly. Curious thing is FF & Chrome handle it differently.
In FF, I open firebug and see the ajax request being made. I see that the request is served in around 300ms but the loading wheel next to the link in the console is still animating for aorund 20 seconds. And after that the json response is properly processed and the result can be seen on the page. In IE also similar behavior, proper processing of the json after 20 seconds.
In Chrome, nothing happens for around 20 seconds after which I see an error in the console saying either "error": undefined or Failed to load resource. Alternatively it also prints the below stacktrace -
POST script.jsp
f.support.ajax.f.ajaxTransport.sendjquery.min.js:4
f.extend.ajaxjquery.min.js:4
DataTableWidget.extend._fetchBuildingBlockItemsPermissionBBItemsWidget.js:91
(anonymous function)PermissionBBItemsWidget.js:83
e.extend.eachjquery.min.js:2
DataTableWidget.extend._loadDataPermissionBBItemsWidget.js:82
DataTableWidget.extend.showPermissionBBItemsWidget.js:15
(anonymous function)permission-building-blocks.html:451
xLAB.min.js:5
ULAB.min.js:5
jLAB.min.js:5
ILAB.min.js:5
eLAB.min.js:5
a.onload.a.onreadystatechange
I dont understand this weird behavior in different browsers.
So in essence I made sure that -
Server side code returns the response fast. I put in some debug statements and saw the server log. None of the response form server take more than 500ms.
Made sure than json is properly validated. The fact that after 20 secs it is processed in both IE & FF without any issues is a proof of that. In addition to use of python's json.tool.
Set the dataType to json
So any pointers on the issue will be a great help. Thanks.
UPDATE
One more curious thing I noticed. While the request is being processed and I hit the refresh button even within 3 seconds of the original request, the process immediately completes. As in I see changes in the view of course fraction of a second later the page is wiped out due to refresh event.
UPDATE 2
I have noticed that after I slice up my big response by alphabets. The issue of looong response happens in only certain responses. I ran this split long response files through http://jsonformatter.curiousconcept.com/#jsonformatter and although it immediately returns saying that the josn is valid, it takes 20+ seconds to actually pretty print the response. I think the problem is happening due to certain characters like \u0026 so with this added info, how to resolve the problem? Here is the snipet of the problematic json.
I figured out the problem. The issue was with how the server-side code provided the client-side code JavaScript with the json string.
I was using a legacy method in our code base which actually rendered the already json string in a jsp page before passing it to the client. This was somehow screwing up the response. Also response type was text/html because of this.
As soon as I switched the response to be of actual application/json MIME type stream, everything was fine.
does your JSON have line feeds? Do you have Firebug or something line that open? The browser may be loading the JSON just fine, it might be your debugging tools crapping out. I Recall having issues before with inspecting certain JSON strings with certain tools just because it didn't have line feeds (or line feeds as understood in Windows). I'm wondering if the fact your logging the whole thing to the console doesn't have something to do with it.
I need some help finding out what's wrong in this code:
ajaxRequest.open("POST", "http://localhost:8181/add", true)
ajaxRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded");
ajaxRequest.send(data);
I'm trying to send data to the server using POST, and ajaxRequest is an ajaxRequestElement().
The problem is when I open the page, the console provided by Chrome to detect Javascript errors says POST http://localhost:8181/add undefined (undefined).
I know the URL is correct and the page receiving the data is ok too, I tried this before in PHP and works fine, so I don't understand what's happening.
It could be that you are posting to http://localhost/add instead of http://localhost:8181/add. Could you simply use 'add' as the url to post your ajax request to?
I have an application in which most requests are submitted via AJAX, though some are submitted via "regular" HTTP requests. If a request is submitted and the user's session has timed out, the following JSON is returned:
{"authentication":"required"}
The JavaScript function which submits all AJAX requests handles this response by showing a popup message and redirecting the user back to the login page.
However, when a non-AJAX request receives this response the JSON is simply shown in the browser because the response is processed directly by the browser (i.e. the aforementioned JavaScript function is bypassed). Obviously this is not ideal and I would like the non-AJAX requests that receive this response to behave the same as the AJAX requests. In order to achieve this, I can think of 2 options:
Go through the application and convert all the requests to AJAX requests. This would work, but could also take a long time!
The JSON shown above is generated by a very simple JSP. I'm wondering if it might be possible to add a JavaScript event handler to this JSP which is run just before the content is displayed in the browser - I'm assuming this would never be called for AJAX requests? This handler could call the other JavaScript code that displays the popup and performs the redirection.
If anyone knows how exactly I can implement the handler I've outlined in (2), or has any other potential solutions, I'd be very grateful if they'd pass them on.
Cheers,
Don
3) Change your AJAX code to add a variable to the GET or POST: outputJson=1
You cannot add a handler to the JSP that way. Anything you add to it will make it a non-JSON producing page.
There are two options that I can see:
Add a parameter to the page by appending a URL parameter to the screen that modifies the output.
URL: http://domain/page.jsp?ajaxRequest=true
would output json only
URL: http://domain/page.jsp
would display a jsp page that could forward to another page.
OR
change the response to have the forwarding code in the JSP that will get executed by the web browser if it is hit directly. Then have your calling AJAX to strip the forwarding code out, and then process what is left.
4) Read up on the 'Accept' request HTTP header.
Then, on the server side tailor the output:
e.g.
if(Accept contains application/json...) { // client asking for json, likely to be XHR
return {"foo":"bar"}
} else { // other
return "Location: /login-please";
}
Start with a smarter error message, like this:
{"error":"authentication required"}
Wrap the JSON output in a callback:
errorHandler({"error":"authentication required"});
Have a handler waiting in your script:
function errorHandler(r) {
alert(r.error);
}
And don't forget to send it down as text/javascript and not application/x-json.