Failing to pass data from client (JS) to server (Flask) with Ajax - javascript

First time ever using jQuery to pass a dictionary filled through a JS script to my server written in Python (Flask) when the user hits a submit button (I read somewhere that AJAX was the way to go).
Something must be broken since in the server function described below, request.get_data() or request.form are None. If any seasoned programmer could give recommendation on how to set up a jQuery request, it would be much appreciated.
In Python, I have the following:
#app.route('/submit',methods=['POST'])
def submit():
info = request.form['info']
action = request.form['action']
...
To handle the dictionary info. On my html file, I load AJAX through:
<head>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
</head>
Define my "submit" button as followed:
<button class="btn" onclick="send(event,'s')" id="SUBMIT">Submit</button>
And handle the action through the script:
<script>
var dict = [];
function send(event,action) {
$.post('/submit', {
info: dict,
action: action
}).done(function() {
}).fail(function() {
});
}
...
</script>

Convert request.form to dictionary and print it you can able get the values
print(request.form.to_dict())

Related

Django AJAX returns undefined instead of the variables

So I have a simple Django script which I've found online for an AJAX function that runs a Python script and gets the output via stdout.
views.py
from django.shortcuts import render
def index(request):
return render(request,'homepage/page.html')
homepage/page.html
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>test</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
$(function()
{
$('#clickme').click(function(){
alert('Im going to start processing');
$.ajax({
url: "static/homepage/js/external_func.py",
type: "POST",
datatype:"json",
data: {'key':'value','key2':'value2'},
success: function(response){
console.log(response.keys);
console.log(response.message);
}
});
});
});
</script>
</head>
<body>
<button id="clickme"> click me </button>
</body>
</html>
So you can see my url is linked to external_func.py which runs after the button is clicked. The script then returns a json.
external_func.py
import sys
import json
import cgi
fs = cgi.FieldStorage()
sys.stdout.write("Content-Type: application/json")
sys.stdout.write("\n")
sys.stdout.write("\n")
result = {}
result['success'] = True
result['message'] = "The command Completed Successfully"
result['keys'] = ",".join(fs.keys())
d = {}
for k in fs.keys():
d[k] = fs.getvalue(k)
result['data'] = d
sys.stdout.write(json.dumps(result, indent=1))
sys.stdout.write("\n")
sys.stdout.close()
However, when I run the server and clicked on the button, the console shows undefined for both values, meaning response.keys and response.message is undefined.
Now, when I instead switch the code to console.log(response) in homepage/page.html. The console prints out the entire external_func.py code in text.
I couldn't find a solution online. It seems like people rarely calls a Python script in an AJAX request, I see a lot of forum posts about AJAX calling for a php code instead.
EDIT1:
I have to clarify one thing. This is just a small section of my project which I want to run some test on. In my actual project, I will have a function in python that takes a long time to compute, hence I prefer to have a webpage partially rendered with a waiting icon while the function processes. The output from the function will then be displayed on a webpage.
You have a django app, and yet you are using CGI for this function? Why? Why not simply make the function another django view? Serving your response with django is much superior to CGI, unless that function significantly bloats or slows down your django. It is as easy as this:
from django.http import JsonResponse
def func(request):
result = ...
return JsonResponse(result)
If you really want to separate this into a CGI script, the most likely reason you are failing to get a response is your web server not being configured to process the CGI request. (Your Developer Tools Network tab is a great help for diagnosing exactly what kind of response you got.) For security reasons CGI is not enabled by default. You need to tell Apache (or whatever web server you are using) that CGI should be enabled for that directory, and that it should be associated with .py files.

How you can save appends to variables an then convert them to php so you can save them in a database?

<html>
<head>
<meta charset="utf-8">
<title>Test page for Query YQL</title>
<link rel="stylesheet" href="http://hail2u.github.io/css/natural.css">
<!--[if lt IE 9]><script src="http://hail2u.github.io/js/html5shiv.min.js"></script><![endif]-->
</head>
<body>
<h1>Test page for Query YQL</h1>
<div id="content"></div>
<input type="button" name="bt1" value="click" onclick="pesquisa()">
<form name="s2">
<input type="text" name="s1">
</form>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="jquery.query-yql.min.js"></script>
<script type="text/javascript">
function pesquisa(){
$(function () {
var t = $('#content').empty();
var url= document.s2.s1.value;
var statement = 'select * from feed where url="'+url+'"';
$.queryYQL(statement, function (data) {
$('<h2/>').text('Test: select * from feed').appendTo(t);
var r = data.query.results;
var ul = $('<ul/>');
$.each(r.item, function () {
$('<li/>').append(this.title).appendTo(ul);
$('<li/>').append(this.link).appendTo(ul);
<?php
$titulo = "<script>document.write(titulo);</script>";
$site = "<script>document.write(site);</script>";
//echo $titulo;
//echo $site;
?>
});
ul.appendTo(t);
});
});
};
</script>
</body>
</html>
How can you save the this.title and the this.link values into 2 different variables an then call them into php so you can insert the data into a DB?
It's just a simple YQL query to search on rss feeds.
After doing the query, I want the results to be saved in a database, but I can't discover how to do that.
First of all, you have to understand that you are working on a Client-Server architecture.
This means:
Let's say that this file you are showing us is called "TestYQL.php" (because you did not say the name of it). This file is executed by php (server side), which reads line by line the contents of it, and generates another new file from the original. For educational purposes, let's say the generated file is called "GeneratedTestYQL.html". This file no longer has any php code inside, since it is directly html and js flat. It knows nothing about php. So there are no php functions, variables, nothing. This last file is the one that reaches the client, and the code is executed by a web browser like Chrome, Firefox, etc.
In your case, the file "TestYQL.php" all you have of php is what is inside the <? Php ....?> Tags. With php you creates 2 variables, each with a tag inside, but without any purpose since they are not used in any way. So, the generated "GeneratedTestYQL.html" file is the same as the original, but without the lines inside the <? Php ...?>.
This means that: The contents of the variables that you use in PHP can be sent to the browser, because with PHP you will generate the file that will be executed in the browser.
Now, when the file "GeneratedTestYQL.html" arrives, the browser starts to show all the contents of the file, it generates the form in which, when you click the button, executes the function pesquisa() and now starts javascript (JQuery) bringing data of the feeds, and for the first time, these variables "this.title" and "this.link" begin to exist in javascript.
Since there is no such thing as php here, you can NOT access those variables from php.
So, how to save that data in a DB?, well, the common way is to send all the data you want from the browser, to the server, then the server sees what to do with that data. To send data from the browser to the server, you do it by making GET or POST requests to a php file from the server (preferably another file, let's say it will be called "saveFeeds.php").
Data can be sent with a GET request, but it is semantically incorrect since GET means you want to fetch data from the server. So to send that data to the server, you will have to make a POST request from the browser, which is more appropriate.
There are now 2 simple ways to make a POST request. The first and most common of these is from a form in the browser, the other way is using Ajax.
How to do it from a form?
Currently in your code, you have already put a form (That is called "s2"), although currently the same is not necessary, but leave that now.
If you wanted to send the data through a form, you should do 2 things. First and most obvious, create the form; second, the data received from the internet (title and link of feed), send them to the server.
Assuming you fetch data from a single feed per url, and the designated file in charge of receiving the request will be "saveFeeds.php". So, you could create a form like the following after the previous one:
<Form class = "sender" action = "saveFeeds.php" method = "post">
  <Input type = "hidden" name = "title" value = ""> <br>
  <Input type = "hidden" name = "link" value = ""> <br>
  <Input type = "submit">
</ Form>
Then you need to put the feed data inside the form, because, at this moment, you can't send anything. You could add a function like:
Function appendFeedToForm (title, link) {
  Var form = $ (". Sender");
  Form.title.value = title;
  Form.link.value = value;
}
And then call it from inside the $ .each of the result as
AppendFeedToForm(this.title, this.link);
The second case, the easiest way to make a request to the same file using Ajax is with a JQuery shortcut:
$.post("saveFeeds.php", r.item);
If you are interested in validations, you can take a look at the JQuery documentation. The important thing about ajax requests is that you can send all the data you want without having to force you to reload the page. Therefore, you can send as many feeds as you want in the same way you would send one.
Now with the data sent from the client to the server, it is necessary to handle the reception of the data. Currently we were pointing all the data to the file "saveFeeds.php", so, now, finally we can put the content from javascript. To access them, simply in that file, you should check the fields:
$ _POST ['title'] // This names are from input names of form
$ _POST ['link'] // or properties sended through Ajax
So, here, you have tp prepare the connection to your database and save those parameters. Currently you did not mention which database engine you are using, so, for this moment, I'll shorten the answer here.
Note: I was not giving you the best practices to solve your problem, but rather the minimum necessary.

Django - Ajax without JQuery lib

I am Learning and using Ajax without jQuery Lib. I created a simple view which renders a random number on to the template. I added a button and called the ajax function. However, clicking the button doesn't change the value on the screen. I checked in DOM (firebug) and it shows the someText.responseText is yielding the whole html rather than just the value, however it has the new value in that HTML. I am sharing this to provide more information on what I have found so far. I am new to this and experimented it with a lot for ex; I have checked "request.is_ajax():" but somehow the view does not find ajax in request. I have printed request on command line and the GET querydict is empty.
Obviously I am not doing something in the correct manner for Django. Please assist.
I have a view;
def home(request):
rand_num = random.randint(1,100)
return render(request, 'home.html', {'rand_num':rand_num})
and html and script;
<html>
<head>
<script type='text/javascript'>
var someText;
function helloWorld(){
someText = new XMLHttpRequest();
someText.onreadystatechange = callBack;
someText.open("GET", "{% url 'home' %}", true);
someText.send();
};
// When information comes back from the server.
function callBack(){
if(someText.readyState==4 && someText.status==200){
document.getElementById('result').innerHtml = someText.responseText;
}
};
</script>
</head>
<body>
<div id="result">{{rand_num}}</div>
<input type='button' value='Abraca dabra!' onclick="helloWorld()"/>
</body>
</html>
here is the url for this view;
url(r'^$', 'socialauth.views.home', name='home'),
I am learning this from an online tutorial.
That is because your AJAX endpoint is the whole view - I.e. your AJAX request asks for the whole rendered template.
What you want is just a number, so make a new view and URL to return just the number, and make the AJAX request to that.
AJAX isn't anything special, its just a way to make an asynchronous request to a URL and get the contents returned.
For reference, a view using something like JSONResponse:
from django.http import JsonResponse
def get_random_number_json(request):
random_no = random.randint(1,100)
return JsonResponse({'random_no': random_no})
Then in your frontend Javascript, fetch url for that view, which will give you only the JSON in your javascript variable via your AJAX call, and instead of all that document.getElementById('result') processing, you can just grab the variable from the json object.

Capture onClick event in serverside php file using Ajax

I am very new to Ajax. My application uses ajax (and a server side php page called Req.php) to fetch records from a database, create table using those fetched records and display it. Now I want a column to be added having Delete option to it. May be something like this:
echo '<td>Delete</td>';
This deleteIt() method lies inside Req.php (server side) file like this:
<script type = "text/javascript">
function deleteIt(rowID)
{
//Some Code
}
</script>
Now considering the fact that it is a server side file, and delete event happens at client side, what should be the procedure to capture this delete event so that it takes $rowID from the table made by server side php file and deletes the correponding record.
Any help would be highly appreciated. And please let me know if there's insufficient information so that I can give more details.
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
jQuery.ajax({
url:'YOUR PHP url which contains DELETE code',
type:'POST',
data:'SEND YOUR DATA',
success:function(results){
jQuery("#oresponsecontainer").html(results);
}
});
In your PHP
$id = $_POST["id"];
An Ajax request would be then be sent from your javascript with the id and action (deleting) of the column your accepping php file would then search for the row and delete it.
please specify what has been done in php for deleting.
You should create another php script that handles POST request (or GET, i've used post ajax)
so function should execute something like this
$.post("/trackDeletion.php",{rowID:rowID},function(successResponse){
//client handler
})
and PHP will be
rowID = $POST['rowID']
//do you code on backend

Passing form data to python

I have an HTML form with data that I would like to send to my SVN. Since HTML/JS have no means of doing this, I want to use Python as a link between the form and the SVN. My problem is that I do not know how to send data from HTML/JS to Python, both of which are client side (there is no server involved).
What I imagined would happen is that a user would fill out the form, then press a 'submit' button, which would call a Python script and pass their form data as arguements.
I have been searching and found that people are running Python server side and POSTing to it from their javascript, but since I have no server I don't think this is possible for me.
Is it possible to send data from HTML/JS to Python if they are both client side?
EDIT: I should add that I do have a good background in Python and JS
Here's a few neat ways of combining Python with JavaScript:
Return data from html/js to python
Note: Since you mentioned you had no server, the request you call with the javascript has to be pointed to the listening port of the socket that the python code runs on.
Easy enouhg would be to listen on port 80 with python and just do regular calls without thinking twice to the :80 from JavaScript.
Basically, HTML form, use JavaScript onSubmit() or a button that calls the AJAX code in the post above, then have Python read the JSON data (structure the <form> data according to the JSON format shown at the top of the link)
Here's a short intro on how to use form data via javascript:
<HTML>
<HEAD>
<TITLE>Test Input</TITLE>
<SCRIPT LANGUAGE="JavaScript">
function testResults (form) {
var TestVar = form.inputbox.value;
alert ("You typed: " + TestVar);
}
</SCRIPT>
</HEAD>
<BODY>
<FORM NAME="myform" ACTION="" METHOD="GET">Enter something in the box: <BR>
<INPUT TYPE="text" NAME="inputbox" VALUE=""><P>
<INPUT TYPE="button" NAME="button" Value="Click" onClick="testResults(this.form)">
</FORM>
</BODY>
</HTML>
Use this principle to gather your information,
then build in the AJAX part in the link mentioned at the top..
Once you've done that, start a python script (shown in the link as well) that listens for these calls.
Remember: To use JSON, format it properly, ' will not be allowed for instance, it has to be "!
In my link, this is the important part that sends the GET request to the "server" (python script):
xmlhttp.open("GET","Form-data",true);
Here's the python part:
from socket import *
import json
s = socket()
s.bind(('', 80)) # <-- Since the GET request will be sent to port 80 most likely
s.listen(4)
ns, na = s.accept()
while 1:
try:
data = ns.recv(8192) # <-- Get the browser data
except:
ns.close()
s.close()
break
## ---------- NOTE ------------ ##
## "data" by default contains a bunch of HTTP headers
## You need to get rid of those and parse the HTML data,
## the best way is to either just "print data" and see
## what it contains, or just try to find a HTTP parser lib (server side)
data = json.loads(data)
print data

Categories

Resources