XMLHttpRequest not being able to make a request to Flask server - javascript

I have setup a simple flask server using the following code:
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
#app.route("/")
def helloWorld():
return "Hello, cross-origin-world!"
if __name__ == '__main__':
app.run(host = '0.0.0.0', port='5000')
From js I am making a request to the address using the follwing code
const theUrl="<myip>:5000/";
var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", theUrl, false);
xmlHttp.send();
console.log(xmlHttp.response);
The console shows
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <title>404 Not Found</title> <h1>Not Found</h1> <p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>
When I try to access the same url from the browser, it returns
Hello, cross-origin-world!
Is there something wrong I am doing with the server? I have tried the js code on a dummy address and I am able to get the contents of that website. There is something wrong with the Flask server.

Just wrote something for file uploads.
Hope this helps.
$('.custom-file-input').change(function () {
console.log($(this)[0].files[0].name);
$('.custom-file-label').text($(this)[0].files[0].name);
var formData = new FormData();
formData.append('file', $(this)[0].files[0]);
var xhr = new XMLHttpRequest();
xhr.open('POST', '/', true);
xhr.send(formData)
I don't understand why one would use XHR for get requests, couldn't you just use Ajax instead?
The last parameter is whether the connection is asynchronous. Perhaps that's what wrong?
Also, don't use Flask built-in webserver for production environment, it just isn't made to cope with more than one user testing for example.
Furthermore, perhaps someone can tell me why not, however, I think you would be better off simply having url as the section of the url after the port declaration, in my example, notice that I only tell jquery or js to post data to / and this is because that means local server, or is interpreted to mean itself, so by default is prepended with your server IP and in this case the port 5000 aswell

Related

Sending data with XMLHttpRequest

I have a website that should send a name to a python script (on a third-party website) when a button is pressed. This python script will then make the name uppercase and return it back to the website.
Right now an XMLHttpRequest is correctly being sent when the button is pressed, but I'm unsure how I correctly send the data with the XMLHttpRequest, and then how this data is accessed in the python script.
XMLHttpRequest:
document.getElementById("myButton").addEventListener("click",
function() {
var myRequest = new XMLHttpRequest();
myRequest.open('GET', 'https://example.com/');
myRequest.onreadystatechange = function () {
if (myRequest.readyState === 4) {
alert(myRequest.responseText);
}
}
myRequest.send("Bob"});
}
);
Python script:
from flask import Flask, jsonify
from flask_cors import CORS
from requests import request
app = Flask(__name__)
CORS(app)
#app.route("/", methods=["GET"])
def hello_world():
return jsonify(name = (name_sent_by_XMLHttpRequest).upper()) # Should return "BOB"
if __name__ == '__main__':
app.run()
I know nothing about javascripts' XMLHTTPRequest but at some point, you need to send the name to the python server, right? HOW to do that is up to you, but a GET based option:
GET request with args: https://example.com/?name=your_name_goes_here
in your flask app, the function listening on route "/" will now have access to that arg, something like
name = request.args.get('name', '')
then you can uppercase() it, and return it in some format - probably XML ?
return Response(my_xml, mimetype='text/xml')
Update based on your comment: usually in a flask function, you would use the flask request object to get your URL parameters. In your example, you're importing the requests module as request, not using it, but clobbering the flask.request namesspace. Change your imports to something like this, and it should work normally:
from flask import Flask, jsonify, request
from flask_cors import CORS
import requests

Django POST Response throws exception if page is refreshed/reopened

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.

Page Redirect and set request custom request header

I am looking for a way to redirect to another web app and set a custom request header. This is manly because the web app that I am going to is expecting a custom header for the user name call "REMOTE_USER" where I will set the user name to.
I was exploring the use of a java servlet or maybe writing some java script to do this.
var client = new XMLHttpRequest();
client.open("POST", "/log");
client.setRequestHeader("REMOTE_USER", "User1");
window.location.href = "http://myserver.com:8080/webapp/";
I am seeing that the page is getting redirected but don't see any custom request headers
function customHeader(remoteinput, userinput) {
var client = new XMLHttpRequest();
client.open("POST", "/log");
client.setRequestHeader(remoteinput, userinput);
window.location.href = "http://myserver.com:8080/webapp/";
}
Now execute your function:
customHeader("something", "user42");
If I am misinterpreting your question, please reply!

How to get HTTP header from Javascript?

I have a Tomcat server that only serves static files(html, css, js). When the request comes in it gets intercepted by a proxy server. Proxy server authenticates the user and adds a userId field to the header and forwards it my Tomcat server.
How can I access userId that has been stored in the header from javascript?
Thank you
You can't, BUT...
If such header is send to the browser you could make an ajax request and get that value from it.
This little javascript could be useful in your case. Watch out, use it with caution and sanitize or change the URL depending on your needs, this is just a "concept", not a copy-paste solution for every case. In many other cases this is not a valid solution, cause it is not the header of the loaded document, but another request. Anyway the server, content-type, etc can be use quite safely.
xmlhttp = new XMLHttpRequest();
xmlhttp.open("HEAD", document.URL ,true);
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4) {
console.log(xmlhttp.getAllResponseHeaders());
}
}
xmlhttp.send();
EDIT: Ooops, seem already anwser that part also... Accessing the web page's HTTP Headers in JavaScript
Didn't read it all.
Use below script for access userId
var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
headers = req.getAllResponseHeaders().split("\n")
.map(x=>x.split(/: */,2))
.filter(x=>x[0])
.reduce((ac, x)=>{ac[x[0]] = x[1];return ac;}, {});
console.log(headers.userId);

How to create an in memory file and upload to server using client side javascript?

I have a test suite written in JavaScript running in a browser that runs on an embedded system. The test suite collects a lot of data and I want to push that to the server. I could use a simple HttpRequest, post-method, but that would require a lot of character escaping to send the content. It would much simpler to upload it to the server as a file using http-file-upload.
Is there a way to create an in memory file and use http-file-upload to push it to a server, using client-side JavaScript?
Since the browser of the embedded system is Ekioh and the system itself is a minimal one, technologies such as flash, JavaApplet, SilverLight are not available. Only pure HTML5 and JavaScript are available.
I think a post would be the better way to do this. Dealing with escaped data is a much easier, more established problem then in-memory files and pushing files to the server with client side javascript. Moreover, escaping data is done for a reason. What you're trying to do is going to welcome a lot of security vulnerabilities.
Try doing something like this.
Snippet taken from Write javascript output to file on server
var data = "...";// this is your data that you want to pass to the server (could be json)
//next you would initiate a XMLHTTPRequest as following (could be more advanced):
var url = "get_data.php";//your url to the server side file that will receive the data.
http.open("POST", url, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");
http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);//check if the data was revived successfully.
}
}
http.send(data);
This worked for me. The key part is to create a file and blob. I use angular JS to do the actual http call. However, once you have a file in memory, it shouldn't be too hard to send the data using your http client.
Note: I do the http call to https://httpbin.org/post. This echoes what the server received/parsed, which is useful while iterating to figure your problem out.
function multiPartPost(bodyObj) {
const url = 'https://httpbin.org/post';
const bodyJson = JSON.stringify(bodyObj);
const blob = new Blob([bodyJson], {
type: 'application/json;charset=UTF-8'
});
const fileName = 'jsonAttrs';
const file = new File([blob], fileName, {type: "text/json;charset=utf-8"});
const formData = new FormData();
formData.append(fileName, file);
return this.$http.post(url, formData, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
});
}

Categories

Resources