simple flask app server passing data with ajax and jquery - python

I've spent all day tinkering with this app trying to get some simple information passed to the back end of the application. I am using a simple flask app and trying to send data from a search query to the back end using ajax. However, I have been completely unsuccessful. Any help would be greatly appreciated.
Below is app.py
from scraper import scrape
from flask import Flask, render_template, jsonify, make_response, request
import json
app = Flask(__name__)
#app.route("/")
def index():
entries = json.dumps(scrape("video games"))
return render_template('index.html', entries= entries)
#app.route('/parse_data', methods=['GET', 'POST'])
def parse_data():
if request.method == "GET":
#data = request.form("blah")
#print("blah")
search = request.json
#new_search = json.dumps(scrape(data))
return search
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0', port=5000)
and index.html
<!DOCTYPE html>
<html>
<head>
<title>Flask app</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
</head>
<body>
<div class="topnav">
<a class="active" href="#home">Home</a>
About
Contact
<form name = "textbox" id = "textbox">
<input id ="textbox" name="textbox" type="text" placeholder="Search..">
<button type="submit">submit</button>
</form>
</div>
<p>you searched: {{search}} </p>
<div id="div1">
<p id="p1"></p>
<p id="p2"></p>
</div>
<script>
var value = $('.textbox').val();
//alert(value);
$.ajax({
type: 'POST',
url: "/parse_data",
data: JSON.stringify(value)
contentType: 'application/json',
success: function(data){
alert("success")
}
});
var jsonz = {{ entries|tojson }};
var s = JSON.parse(jsonz);
var i;
for (i = 0; i < s.length; i++) {
var para = document.createElement("p");
var node = document.createTextNode(s[i].product_name + "\n" + s[i].product_link);
para.appendChild(node);
var element = document.getElementById("div1");
element.appendChild(para);
}
//document.getElementById("user").innerHTML =
//obj;
//"Name: " + obj.product_name + "<br>" +
//"Location: " + obj.product_link;
</script>
</body>
</html>

Your code snippet has a few issues, mostly:
Your AJAX request is not bind to the button click event, so clicking the button does nothing.
You have two html elements with the same id textbox, id are supposed to be unique.
To get an html element by id use "#textbox"
On the server side (Flask):
Use the function get_json() of the request
To process the POST request you need to check for POST not GET
Try wrapping your POST request like this:
$("button").click(function (e) {
e.preventDefault();
var value = $("#textbox").val();
alert(value);
$.ajax({
type: "POST",
url: "parse_data",
data: JSON.stringify({ "text" : value } ),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
alert(JSON.stringify(data));
}
});
});
Also remove the duplicate ids textbox, change the id of the form to something like textbox-form, finally change your parse_data function to something like this:
#app.route('/parse_data', methods=['GET', 'POST'])
def parse_data():
if request.method == 'POST':
search = request.get_json()
return jsonify(search)
return render_template('index.html')

Related

How to upload a (csv) file with an AJAX call and Flask

I'm updating on updating an older project that uses AJAX and have decided to use Flask to do so. For the particular page I'm currently working on, I need to be able to upload a CSV and read the data in the file (no need to save it). I have several other pages that work using AJAX, but they return form data back to Flask (e.g. what semester it is, what year it is, etc). Ideally, I'd like to be able to upload the CSV and read the form data (the variables I have called formData and myFormData below).
I have found this post and based my MWE on it, but when I look at request.files, I get an empty dictionary. Here is the code I have:
run.py:
import os
from app import app
if __name__ == "__main__":
port = int(os.environ.get("PORT", 5000))
app.run(host='0.0.0.0', port=port, debug=True)
__init__.py:
from flask import Flask, session
import flask_excel as excel
from fileUpload import fileUpload_bp
def create_app():
app = Flask(__name__, template_folder="templates")
app.secret_key = 'flask-ajax file upload test'
app.register_blueprint(fileUpload_bp)
excel.init_excel(app)
return app
app = create_app()
file_upload.py:
from flask import Flask, render_template, request, Blueprint
fileUpload_bp=Blueprint('fileUpload',__name__)
#fileUpload_bp.route('/fileUpload',methods=['GET','POST'])
def fileUpload():
if request.method=="POST":
print(request.files)
return render_template("fileUpload.html")
fileUpload.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>file upload test</title>
<script type="text/javascript"
src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script type="text/javascript"
src="static/scripts/fileUpload.js"></script>
</head>
<body>
<form action="javascript:fileUpload()" method="POST" enctype="multipart/form-data">
<input type="file" id="file_upload_data"><br>
<input type="text" id="form_data" value="sample data">
<button type="submit">Upload</button>
</form>
</body>
</html>
fileUpload.js:
function fileUpload()
{
var formData=new FormData($("file_upload_data")[0]);
var myFormData={form_data: $("#form_data").val()};
$.ajax({
type: 'post',
dataType: 'html',
url: 'fileUpload',
async: false,
data: formData,
contentType: false,
cache: false,
processData: false,
success: function (data){
console.log('Success');
},
error: function(response, status, xml) {
console.log('failure');
}
});
}
A little additional info: This is part of a larger project which is why I'm using Blueprints and flask_excel. I've seen folks recommend using something other than AJAX, but I'm trying to make the pages run with python3 by using Flask without rewriting everything that's already there.
So that the form can be serialized, it is necessary for the input fields to have a name attribute.
I'm using the form's submit event in the following minimal example. The event listener is registered when the document is fully loaded. When the form is submitted, the form data is serialized and sent via ajax.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Upload</title>
</head>
<body>
<form name="upload-form" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<button type="submit">Upload</button>
</form>
<script type="text/javascript"
src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
// Register the listener for submit events.
$('form[name="upload-form"]').submit(function(evt) {
// Prevent the form from default behavior.
evt.preventDefault();
// Serialize the form data. The entire form is passed as a parameter.
const formData = new FormData($(this)[0]);
// Send the data via ajax.
$.ajax({
type: 'post',
url: '/upload',
data: formData,
contentType: false,
cache: false,
processData: false,
}).done(function(data) {
console.log('success');
}).fail(function(xhr, status, error) {
console.error('error');
});
});
});
</script>
</body>
</html>
The server-side code remains essentially the same. However, I advise you, for reasons of cleanliness, to separate endpoints for ajax requests from those that return html.
from flask import Flask
from flask import make_response, render_template, request
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/upload', methods=['POST'])
def upload():
print(request.files)
return make_response('', 200)

Flask cannot redirect after receiving post request from Ajax in templates

I want to create a chatroom, in which, if people enter "!exit", then they will get out of the chatroom. The way I implement this idea is that whenever people send "!exit" message, Ajax will send a post request back to the view function. After receiving the request, the view function redirects the user to the homepage. However, right now, I think I can send a post request, since the console prints "success", but the code still does not redirect. This is my code:
In chat.html:
<head>
<title> Chat room </title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.8/socket.io.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
</head>
<body>
<script type="text/javascript">
$(document).ready(function() {
var socket = io.connect('http://127.0.0.1:5000');
socket.on('message', function(msg) {
if (msg=="!exit") {
$.ajax({
type : "POST",
url : "http://127.0.0.1:5000/chat",
data: {data: "Unmatched"},
contentType: 'application/json;charset=UTF-8',
success: function() {
window.location.href = '/chat'
}
});
}
else {
$("#message-display").append('<div>'+ "person: " + msg+'</div>');
}
});
$('#sendbutt').on('click', function() {
socket.send($('#message-input').val());
$('#message-input').val('');
});
});
</script>
<div> Welcome to the chat room. You are chatting with a user. </div>
<div> Type "!exit" if you want to stop chatting and return to the homepage. </div>
<l id="message-display"> </l>
<input type="text" id="message-input">
<button id="sendbutt"> Send </button>
</body>
</html>
In main.py:
socketio=SocketIO(app)
#app.route('/', methods = ["GET", "POST"])
def homepage():
return render_template('home.html')
#app.route('/chat', methods = ["GET", "POST"])
def chat():
if request.method == "POST":
return redirect(url_for('homepage'))
return render_template("chat.html")
#socketio.on('message')
def handle_message(msg):
send(msg,broadcast=True)

Send variables from Python Flask to HTML

I have following Problem:
i want to send some data to Html from Python with button Click in HTML, but wenn i click the button it doesn't work at all.
Here is my code:
*
python.py:
from flask import Flask, render_template, flash, Markup, request
app = Flask(__name__)
#app.route('/')
def index():
return render_template('new.html')
#app.route('/SomeFunction', methods = ['POST', 'GET'])
def SomeFunction():
if request.method == 'GET':
text = 'Name'
print("result:")
return render_template("new.html",text = text)
if __name__ == '__main__':
app.run()
and here is my Html:
<!doctype html>
<html>
<head>
<title>The jQuery Example</title>
<div class="flashes">
{% for message in get_flashed_messages()%}
{{ message }}
{% endfor %}
</div>
<h2>jQuery-AJAX in FLASK. Execute function on button click</h2>
<script type="text/javascript" {{ url_for('static', filename='app.js')}}></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"> </script>
<script type=text/javascript> $(function() { $("#mybutton").click(function (event) { $.getJSON('/SomeFunction', { }, function(data) { }); return false; }); }); </script>
</head>
<body>
<input type = "button" id = "mybutton" value = "Click Here" />
<p>text: {{text}}</p>
</body>
</html>
So what i want is when i press the input button it will show the name what is in python defined. Maybe there are other ways what can make it works, but i need exactly in python.
Okay so passing variables from python flask to html is easy.
Import json
make a dictionary object with key whatever you want and assign your variable to that key
jobj = { 'name' : name }
Now dump this object as json and pass as argument
return render_template('htmlfile.html', res=json.dumps(jobj))
Now you would be able to access the res json in JavaScript in htmlfile.html
<Script>
var res = JSON.parse(' {{ res | safe }} ');
console.log(res.name);
</Script>

Python flask upload file using ajax request.files empty

I am trying to upload an image about 1.62MB to an end point written using flask. the request.files object is always empty. I've checked the following questions but no luck:
Flask request.files is empty
https://github.com/requests/requests/issues/2505
How to upload a file using an ajax call in flask
here is my server:
from flask import Flask, request, jsonify, render_template
import sys
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = r"C:\Temp"
app.debug = True
#app.route("/demo-upload", methods=["GET", "POST"])
def ProcessImage():
if request.method == "POST":
print(request.files)
try:
if 'file' in request.files:
with open("test-upload.png", "wb") as iFile:
print(request['file'])
iFile.write(request.files['file'])
except Exception as e:
print(e)
return jsonify("Ok")
#app.route("/", methods=["GET"])
def DemoIndexPage():
return render_template("index.html")
if __name__ == "__main__":
app.run()
my client:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<script src="https://code.jquery.com/jquery-2.2.4.min.js"
integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
crossorigin="anonymous"></script>
<title>Demo</title>
</head>
<body>
<h1 style="text-align: center">Status Demo</h1>
<span>upload image to process.</span><br/>
<form id="FileForm" name="file" enctype="multipart/form-data">
<input type="file" name="file" id="File" />
<input type="button" name="submit" value="submit" onclick="ProcessImage()" />
</form>
<p id="status" hidden>Success!</p>
<script>
function ProcessImage()
{
var form_data = new FormData($('#File')[0]);
console.log(form_data)
$.ajax({
type: 'POST',
url: '/demo-upload',
data: form_data,
contentType: false,
cache: false,
processData: false,
async: false,
success: function (data) {
console.log('Success!');
$("#status").show();
},
});
}
</script>
</body>
</html>
everything looks clean to me and I do not know where I am going wrong. the files attribute in the request object is always empty. I also tried with postman using post request with form-data key = file and value = uploaded a file, and a header content-type = "multipart/form-data". any help is appreciated thanks a lot!
I made a few changes and make it work:
First, change which html element you read the data from in javascript part:
var formDataRaw = $('#FileForm')[0];
var form_data = new FormData(formDataRaw);
Second, I tried to obtain the uploaded image as follows: (#cross_origin() is only required if you try to upload to your localhost)
#app.route("/demo-upload", methods=["GET", "POST"])
#cross_origin()
def ProcessImage():
if request.method == "POST":
print(request.files)
try:
if 'file' in request.files:
imageFile = request.files['file']
savePath = "/somewhere/somewhere/something.png"
imageFile.save(savePath)
except Exception as e:
print(e)
return jsonify("Ok")

How to use data provided by Ajax in flask?

So I was starting out with Flask and thought of creating a Youtube search engine wherein I will be taking data from the user through Html from and send that data to Flask using Ajax.
Here is the code for my index html page:
{% extends "layout.html" %}
{% block content %}
<script type=text/javascript>
$(function() {
$("#echoText").keyup(function() {
$.ajax({
type: "GET",
url: $SCRIPT_ROOT + "/echo/",
contentType: "application/json; charset=utf-8",
data: { echoValue: $('input[name="echoText"]').val() },
success: function(data) {
$('#echoResult').text(data.value);
}
});
});
});
</script>
<strong>Enter a value to echo back:</strong>
<input type='text' size='10' id='echoText' name='echoText'>
<button type='button' id='submitBtn' name='submitBtn'>Submit via AJAX</button><br /><br />
<div id='echoResult'></div>
{% endblock %}
And here is my flask app python file:
from flask import Flask, jsonify, render_template, request
import youtube
app = Flask(__name__)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/echo/', methods=['GET'])
def echo():
ret_data = {"value":youtube.youtube_search(request.args.get('echoValue'))[1][0]["id"]["videoId"]}
data = jsonify(ret_data)
return data
if __name__ == '__main__':
app.run(port=5000, debug=True)
So right now I am able to transfer the data from Html page to flask but I some how want to use the data return a YouTube video embedded in my Html page. How can I do that?

Categories