I'm using Django in order to create a server which will download and track the progress of files. It has an input field for the url of the download link, and once I click on Download, it executes the following javascript code:
index.html
function startDownload() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
completedFile = xhttp.responseText;
document.getElementById(completedFile + "ProgBar").style.width = "100%";
document.getElementById(completedFile + "ProgBar").innerHTML = "Completed!";
setTimeout(delProgBar, 5000, completedFile);
}
};
xhttp.open("POST", "http://localhost:8000/download/start/", true);
xhttp.setRequestHeader("X-CSRFToken", '{{ csrf_token }}');
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
var downloadLink = document.getElementById("downloadInput").value;
var sendString = "url=" + downloadLink;
var downloadArray = downloadLink.split('/');
var downloadName = downloadArray[downloadArray.length-1];
addProgBar(downloadName, "0");
xhttp.send(sendString);
}
Django views.py
def start(request):
aux = request.POST['url']
file_name = start_download(aux)
print("###########")
print(file_name)
return HttpResponse(file_name)
This works completely fine IF I don't reload the page after starting the download. The POST Request is only being logged on Django Command Prompt window after it is completed (readyState check).
However, the page should show the download progress for other people that open the page after the download started. This however is throwing a big error on Django, with something like 4 Exceptions. I can post it later if necessary, but the main one seems to be:
ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine
I believe that what I'm doing wrong is trying to send a response to a client that did not generated the request.
Is there a way to receive the POST Response even if the client did not sent the original Request? Or is there another way to do what I'm trying to?
Thanks a lot!
Additional Info:
Tried with GET instead of POST and the same issue happens.
I believe that the main issue here is that the POST Request is only returning an answer to the client once the operation "start_download" finishes, which can take a while. I should instead send a response with "success" or "fail" to start the download and use GET Request to perform polling and get the download status.
Firstly it looks like the code checks for POST values.
To fix this check if the request method is POST or GET. If its GET then you need to render to a page that displays the progress of the files.
Related
Heres my email sending function:
function send() {
var key = "dJdJekCVAFIqvUJ13DEczZjgIh_4MyeIGEHz2GBYKFe";
var message_name = "defender_send_message";
var data = {};
data.value1 = document.getElementById('textBox').value;
data.value2 = localStorage.getItem("AdminsEmail");
var url = "https://maker.ifttt.com/trigger/" + message_name + "/with/key/" + key;
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
if (xmlhttp.status == 200) {
console.log("Message Sent");
}
}
}
xmlhttp.open('POST', url, true);
xmlhttp.responseType = 'json';
xmlhttp.send(new FormData(data));
}
I wanted to create an email sending function with only pure js, not jquery or anything. I get the following errors when i click send:
(ignore the first error i fixed that already)
I had a jquery function that worked (but i had to get rid of it):
var message = localStorage.getItem("Message");
console.log(message + localStorage.getItem("AdminsEmail"));
var key = "dJdJekCVAFIqvUJ13DEczZjgIh_4MyeIGEHz2GBYKFe"; // << YOUR KEY HERE
var message_name = "defender_send_message"; // << YOUR MESSAGE NAME HERE
var url = "https://maker.ifttt.com/trigger/" + message_name + "/with/key/" + key;
$.ajax({
url: url,
data: {value1: message,
value2: localStorage.getItem("AdminsEmail")},
dataType: "jsonp",
complete: function(jqXHR, textStatus) {
console.log("Message Sent");
}
});
why would this work and my other function not?
EDIT 2 : Since it seems the endpoint doesn't actually return JSON, I think your original jQuery code wasn't correct either. You need to do more research into this iftt.com platform and how to use it. From what I can tell, it's meant to be used in a mobile app, not in the browser- it would be a normal POST XHR then, and CORS doesn't apply to mobile apps. They have this page for testing the endpoint- notice that it gives you an example using curl, a command-line tool, where again CORS doesn't apply. So I think you need to rethink things, this service is not designed to be used from a browser, like you are trying to do.
EDIT: since it turns out you are actually trying to use JSONP and not a plain XHR, all you need to do is implement that without jQuery- create a script tag with the server's URL and add a URL parameter to define your callback function to handle the data. This answer should give you the solution.
In your case the code might look like this :
http://www.codeply.com/go/bp/VRCwId81Vr
function foo(data)
{
// do stuff with JSON
console.log(data)
}
var script = document.createElement('script');
script.src = "https://maker.ifttt.com/trigger/defender_send_message/with/key/"+
"dJdJekCVAFIqvUJ13DEczZjgIh_4MyeIGEHz2GBYKFe?callback=foo";
document.getElementsByTagName('head')[0].appendChild(script);
Note that this doesn't work for me(but with your code, you would get Message sent printed to the console, so maybe you thought it was working?)- the response isn't JSON. Most likely the endpoint isn't actually meant to be used for JSONP?
My answer below only applies if you are trying to do a regular XHR in a browser without JSONP.
This happens because of the Cross Origin Resource Sharing policy of your browser. Your code is hosted at localhost, and it is trying to access a resource hosted at maker.ifttt.com through an XmlHttpRequest. In order to allow this to happen, the server at maker.ifttt.com would need to be configured to allow access from the localhost origin. Presumably you can not make that change as you don't control that server.
In your case, the best solution would be to make the request to maker.ifttt.com through your own server- CORS doesn't apply for server-to-server requests. Send the XmlHttpRequest to your server, take the data regarding the email from the request URL parameters, and then make the request to maker.ifttt.com using that data.
I am trying to send data by Ajax with the Post method, but the answer gives me 302 (Found) and I do not know what it can be. This is my code:
function sendData(){
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
console.log("Response" + xmlhttp.responseText);
}
}
xmlhttp.open("POST", "request.php", true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send("name="+document.getElementById('username').value);
}
and my .php file only print a message
<?php echo 'hello : ' . $_POST["name"] ?>
The 302 status code indicates that the resource you are requesting has redirected to another resource. If this is behind some authentication, or requiring a session to be active then yes, it would follow that the session timing out is responsible for the ajax resource being called to redirect to possibly a login screen maybe.
Try to use jQuery request, as it much simpler - also recommended in the above comments!
One way to get such a message is, to forget to add a / to the end of a URL, which is a "sub-directory" of the document root. As the URL your.domain/whatever and your.domain/whatever/ might not be the same. (Depending on server configuration, and the actual application serving those URLs.)
I can see, in this case you are actually POSTing to /request.php, so this might not apply, but just in case, I'd try to make that request 'by hand' and see what happens.
There are many browser plugins, that let you generate AJAX queries.
I am trying to access a diagram (the type of url is image), which require authorization, and display it in fancybox. So I tried to use XMLHttpRequest to send authorization in header first and access this url again since the authorization has already bypassed in cache, that's why I set async to false. Here is my code:
function showDiagram(row){
var authCode = $("#authCode").text();
var header = "basic" + authCode;
console.log("In show diagram");
var id = row.children().eq(6).text();
openURL = restURL + "/service/runtime/process-instances/" + id + "/diagram";
console.log(openURL);
var xhr
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}
else{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.open("GET", openURL, false);
xhr.setRequestHeader("Authorization", "Basic " + authCode);
xhr.send();
console.log(xhr.status);
if(xhr.status==200){
callFancybox(openURL);
}else{
alert("The diagram cannot be shown!");
}
}
However, I have met two different error situations.
The browser still ask me to enter username and password when I access the url for the first time, at the same time, console print out status = 200 and fancybox has already popped up, if I refuse to enter password, a GET 401(Unauthorized) error will be returned. If I entered the password, the diagram will show in fancybox and it will work well for all other url I am trying access.
Console print out status = 200 and the fancybox will pop and show "The requested content cannot be loaded.
Please try again later." And a GET 401(Unauthorized) error will be returned.
Why this happening? What should I do to bypass auto login and display the url in fancybox? Thank you very much for any ideas!
You're not specifying what is on the server side, and the problem is there. You must modify your server so that it supports your header authentication. With your current implementation the server is ignoring the headers, and so it's challenging you to indentify in a different way.
Besides you'r not sending any kind of credentials or whatever. You must add headers with that information.
I am trying to use a vanilla JS AJAX request to pull back a JSON string from a locally stored JSON file (specifically trying not to use JQuery) - the below code is based on this answer - but I keep getting an error in the Chrome console (see below). Any ideas where I'm going wrong? I have tried changing the positioning of the xhr.open & .send requests, but still get error messages. I suspect the issue lies with the .send() request?
//Vanilla JS AJAX request to get species from JSON file & populate Select box
function getJSON(path,callback) {
var xhr = new XMLHttpRequest(); //Instantiate new request
xhr.open('GET', path ,true); //prepare asynch GET request
xhr.send(); //send request
xhr.onreadystatechange = function(){ //everytime ready state changes (0-4), check it
if (xhr.readyState === 4) { //if request finished & response ready (4)
if (xhr.status === 0 || xhr.status === 200) { //then if status OK (local file || server)
var data = JSON.parse(xhr.responseText); //parse the returned JSON string
if (callback) {callback(data);} //if specified, run callback on data returned
}
}
};
}
//-----------------------------------------------------------------------------
//Test execute above function with callback
getJSON('js/species.json', function(data){
console.log(data);
});
The console in Chrome is throwing this error:
"XMLHttpRequest cannot load file:///C:/Users/brett/Desktop/SightingsDB/js/species.json. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource."
Would be grateful for any insights - many thanks.
Basically as Felix, error msg, et al below say - simply can't run an AJAX request against a local file.
Thanks.
Try to run the application on local server like apache or wamp then you will not face any issue
I am using a REST service to generate a CSV file that I want to prompt the user to download. An example of the service is below:
https://localhost:8444/websvc/exportCSV?viewId=93282392
To prompt the user to download the file, I use this code:
window.location.href = exportUrl, where exportUrl would be a URL like the one above.
This works great if there are no errors on the server when executing the service. The file download prompt appears, the page doesn't refresh, and all is well.
However, if there is an error, I'm getting a nasty HTTP Status 500 page, which is no good for user experience. What I'd like to do is catch any error on the resulting page, and throw up a more friendly error without leaving the current page. I tried:
try {
window.location.href = exportUrl;
}
catch (e) {
alert(e);
}
But that doesn't seem to change the behavior at all. Does anyone have any ideas on how to handle this?
Thanks very much.
Catching an error like that will only catch a JavaScript error. That's not what you're experiencing here. Your server is returning a status code of 500. You need to make sure that everything is good BEFORE you send your users there.
To do that you could effectively 'ping' the URL with Ajax to ensure that it won't return a 500 error.
Something like the following:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200) {
window.location.href = exportUrl;
}
}
xhr.open('head',exportUrl);
xhr.send(null);
This would do a HEAD request to the URL to ensure that there are no nasty server errors waiting.
Of course, if in the process of actually GENERATING the CSV your server throws an error - it would still return a 500.
A more robust way would be to get the data via Ajax, build a data URL via base64encode and then set window.location.href to that data URL.
By doing that, you could also ensure that the Ajax didn't return a 500 and you got the data you were expecting in the response.
Hope this helps!