Import a variable from Flask to a webpage without reloading it - javascript

I would like to import the variable test_data from Flask to my webpage, without reloading it. Just clicking a button. But I couldn't succeed so far. Any ideas?
Flask:
#blueprint.route('/data_analysis')
#login_required
def data_analysis():
test_data = 'getting data from here' ### THIS VARIABLE
return render_template('index.html', test_data= test_data)
Javascript:
$("#load_data_btn").click(function(){
var request = new XMLHttpRequest();
request.open('GET', '/home/data_analysis', true);
request.onload = function() {
if (this.status >= 200 && this.status < 400) {
var test_data = {{ test_data }};
alert(test_data);
// Success!
var resp = this.response;
} else {
// We reached our target server, but it returned an error
}};
request.onerror = function() {
// There was a connection error of some sort
};
request.send();
});

It looks like you're confusing Jinja which renders the html and javascript file before sending it to the client, and the server side stuff. What you're doing is creating an html file that will have something like:
<script>
. . .
var test_data = "getting data from here"; # hard coded when user visits site
alert(test_data); # rather than dynamically retrieved
. . .
</script>
But you're code probably isn't getting here because you're route isn't actually returning anything.
If you don't want to reload the page you should return the variable encoded as JSON rather than render the template:
from flask import jsonify
#blueprint.route('/data_analysis')
#login_required
def data_analysis():
return jsonify({"value": "getting data from here"})
$("#load_data_btn").click(function(){
$.getJSON("/home/data_analysis", function(response){
alert(response["value"]);
});
});

Related

Unable to make php $_REQUEST from XMLHttpRequest data

I am trying to make XMLHttpRequest from my html frontend to the php microservice backend, sending data from the input to be manipulated, and displayed on html output
The function I am trying to execute is triggered by 'onlick'
Frontend
function markRequired()
{
input_text = document.getElementById('input-text').value
input_text2 = document.getElementById('input-text2').value
let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var j = JSON.parse(this.response);
mark_required = j.answer;
displayMark();
}
};
xhttp.open("GET",markURL+"?input_text="+input_text+"?input_text2="+input_text2);
xhttp.send();
return;
}
}
Backend
<?php
header("Access-Control-Allow-Origin: *");
header("Content-type: application/json");
require('functions.inc.php');
//main array
$inputtext = $_REQUEST['input_text'];
$furthertext = $_REQUEST['input_text2'];
$totalsofar = getTotal($inputtext, $furthertext) // In php unittest the function works, so i know it's not the problem
$output['string']=$inputtext."=".$answer;
$output['answer']=$totalsofar;
echo json_encode($output);
exit();
Whenever I run my html front end and call the function, markRequired() I am not getting any response. Status code is 200 and I can see the sent data in the request URL.
When I try to return the input string, I am getting a null response.
I can't use cURL for this particular project otherwise I would have.
Any help would be much appreciated!!

How get steam nickname via javascript

Hello i now using this php code for get steam nicknames
function EchoPlayerName($steamid){
$xml = simplexml_load_file("http://steamcommunity.com/profiles/$steamid/?xml=1");//link to user xml
if(!empty($xml)) {
$username = $xml->steamID;
echo $username;
}
}
or
$steam = file_get_contents("http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key={API_KEY}&steamids=$steamid64", true);
$steamarray = json_decode($steam, true);
$name = $steamarray['response']['players'][0]['personaname'];
but i this using for listing players and loading page is slow
so i want this data load via javascript after full load page
any ideas?
API example
{"response":{"players":[{"steamid":"76561197964477177","communityvisibilitystate":3,"profilestate":1,"personaname":"The [G]amerX #π—™π—¨π—‘π—£π—Ÿπ—”π—¬.𝗽𝗿𝗼","lastlogoff":1558765863,"commentpermission":1,"profileurl":"https://steamcommunity.com/id/gamerxcz/","avatar":"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/66/6673d6df066386d232164e8f9a5d9b36cad1d013.jpg","avatarmedium":"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/66/6673d6df066386d232164e8f9a5d9b36cad1d013_medium.jpg","avatarfull":"https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/66/6673d6df066386d232164e8f9a5d9b36cad1d013_full.jpg","personastate":0,"realname":"Community Owner","primaryclanid":"103582791433644720","timecreated":1076786008,"personastateflags":0,"loccountrycode":"CZ"}]}}
First, you should get Data using ajax of pure javascript or jquery. Then you should target an HTML element that you want to fill it using this retrieved data. Imagine element with ID target.
jQuery:
$(document).ready(function () {
$.ajax({
url: "http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key={API_KEY}&steamids=$steamid64",
}).done(function (data) {
var json = JSON.parse(data);
$('#target').text(json['response']['players'][0]['personaname']);
});
});
pure javascript:
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key={API_KEY}&steamids=$steamid64');
xhr.onload = function () {
if (xhr.status === 200) {
var json = JSON.parse(xhr.responseText);
document.getElementById('target').innerHTML = json['response']['players'][0]['personaname'];
} else {
alert('Request failed. Returned status of ' + xhr.status);
}
};
xhr.send();
Remember to place these scripts at the end of your document.

Flask - use javascript to display loading page while waiting for task to complete [duplicate]

This question already has an answer here:
Flask - render template asynchronously
(1 answer)
Closed 5 years ago.
In menu.html, a click on an given link renders the chosen page, pasta.html, in this fashion:
<ul>
<li><a href="{{ url_for('pasta') }}";>Pasta</a>
<form action="{{ url_for('handle_menu') }}" method="post">
<input type="radio" name="additive" value="Cheese"> <label style="font-size: 11px;">Cheese</label>
</form>
</li>
but let's say #app.route('/pasta') has to 'cook' some 'ingredients' before it's 'done':
#app.route('/pasta')
def pasta():
# (perform some long task here)
return render_template('pasta.html')
for that matter I would like to display a /cooking view while the page loads, like so:
#app.route('/cooking')
def cooking():
return render_template('cooking.html')
If I'm not mistaken, with Flask and jinja2 templates you either return (200) or redirect (301) a page, and for any intermediate page like loading.html, you need javascript.
So, how can I use javascript here in order to display cooking.html page while waiting for /pasta task to complete, and once the task is done, finally return it?
Since you're using a GET request, you can have your anchor tag route to cooking, render the cooking.html template, then use window.location.replace() to redirect to pasta. The long task in pasta() will be performed before pasta.html is rendered.
In menu.html:
Pasta
In cooking.html:
<script> window.location.replace('/pasta'); </script>
In the case of a POST request, you would need to send the form values to cooking, pass them to the template, then send them again to pasta using AJAX, and finally redirect in the callback function.
In menu.html:
<form action="{{ url_for('cooking') }}" method='POST'>
In cooking():
#app.route('/cooking')
def cooking():
return render_template('cooking.html', form_data=request.form['form_data'])
In pasta():
#app.route('/pasta', methods=['GET', 'POST'])
def pasta():
if request.method == 'GET':
render_template('pasta.html')
# (perform some long task here)
return make_response('POST request successful', 200)
In cooking.html:
<script>
$.ajax({
type: 'POST',
url: '/pasta',
data: {
form_data: '{{form_data}}',
},
success: function() {
window.location.replace('/pasta');
}
});
</script>
You'll need to create a third endpoint called cooking_request:
/cooking_request
/cooking
/pasta
Render the /cooking_request page and have javascript in there to call the /cooking page using Ajax. When /cooking responds, you'll then request the /pasta contents and display to the user.
Here's an example code you could use in your /cooking_request page. It will call the /cooking page, wait for it and finally render /pasta inside the div#pasta-results element.
<div id="pasta-results">Please wait, loading...</div>
<script type="text-javascript">
function loadPasta() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("pasta-results").innerHTML = this.responseText;
}
};
xhttp.open("GET", "http://website-host/pasta", true);
xhttp.send();
}
function loadCooking() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
loadPasta();
}
};
xhttp.open("GET", "http://website-host/cooking", true);
xhttp.send();
}
loadCooking();
<script>

How to pass Django csrf token in AJAX (without jQuery)

Based on the w3schools ajax example I am trying to make a delete call and then remove the corresponding row from a table. There are plenty of answers here about how to do it using JQuery but I am not doing that. I found this answer which made me write my JavaScript like this:
function deleteFullLicense(rowid, objectid) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 204) {
row = document.getElementById(rowid);
row.parentNode.removeChild(row);
}
else {
window.alert("Something went wrong. The delete failed.");
}
};
xhttp.open("POST", "deleteLicense/" + objectid, true);
xhttp.send({'csrfmiddlewaretoken': '{{ csrf_token }}'});
}
But I get the Forbidden (CSRF token missing or incorrect.) message. How should I send the token?
Turns out if I called it X-CSRFToken instead it worked. Found out about it here if you want to read more.
function deleteFullLicense(rowid, objectid) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 204) {
row = document.getElementById(rowid);
row.parentNode.removeChild(row);
}
};
xhttp.open("POST", "deleteLicense/" + objectid, true);
xhttp.setRequestHeader("X-CSRFToken", '{{ csrf_token }}')
xhttp.send();
}
The header name X-CSRFToken actually comes from the parameter CSRF_HEADER_NAME in Django settings.py. When receiving frontend request (e.g. ajax call), Django internally checks header parameters and converts X-CSRFToken to HTTP_X_CSRFTOKEN which is default value of CSRF_HEADER_NAME .
The better approach would be to :
convert the value of CSRF_HEADER_NAME
render the converted value in previous step, to the HTML template
in the frontend code (e.g. the HTML template or separate js file), create a custom header with that value and the CSRF token on each ajax call for form submission.
Here's a quick example :
In settings.py
CSRF_HEADER_NAME = "HTTP_ANTI_CSRF_TOKEN"
In the view function of views.py
from django.conf import settings
from django.http.request import HttpHeaders
prefix = HttpHeaders.HTTP_PREFIX
converted = settings.CSRF_HEADER_NAME[len(prefix):]
converted = converted.replace('_','-')
# so the value HTTP_ANTI_CSRF_TOKEN is converted to ANTI-CSRF-TOKEN,
return Response(context={'custom_csrf_header_name':converted})
In your HTML template (not good practice, since this is just quick example)
<script>
// Note that the value is 'ANTI-CSRF-TOKEN'. when this header name goes to
// backend server, Django will internally convert it back to 'HTTP_ANTI_CSRF_TOKEN'
var custom_csrf_header_name = "{{ custom_csrf_header_name }}";
// the ajax part is almost the same as described in the accepted answer
...
xhttp.setRequestHeader(custom_csrf_header_name, '{{ csrf_token }}')
...
</script>

I can't send PHP variables to JavaScript

I'm trying to send parametres from a .php file to my Javascript but I can't even manage to send a String.
Javascript fragment:
var params = "action=getAlbums";
var request = new XMLHttpRequest();
request.open("POST", PHP CODE URL, true);
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.setRequestHeader("Content-length", params.length);
request.setRequestHeader("Connection", "close");
request.send(params);
request.onreadystatechange = function() {
var phpmessage = request.responseText;
alert(phpmessage);
};
PHP fragment:
$deviceFunction = $_POST["action"];
if ($deviceFunction == "") $deviceFunction = $_GET["action"];
// Go to a function depending the action required
switch ($deviceFunction)
{
case "getAlbums":
getAlbumsFromDB();
break;
}
function getAlbumsFromDB()
{
echo "test message!";
}
The alert containing phpmessage pops up but it's empty (it actually appears twice). If I do this the alert won't even work:
request.onreadystatechange = function() {
if(request.status == 200) {
var phpmessage = request.responseText;
alert(phpmessage);
}
};
The readystatenchange event will be called each time the state changes. There are 5 states, see here: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#readyState
Rewrite your JS:
request.onreadystatechange = function () {
if (request.readyState == 4) {
console.log('AJAX finished, got ' + request.status + ' status code');
console.log('Response text is: ' + request.responseText);
}
}
In your code, you only check for the returned status code. The code above will check for the ready state and then output the status code for debbuging.
I know that this answer is more a comment than an answer to the actual question, but I felt writing an answer in order to include nicely formatted code.
I faced a similar problem working with Django. What I did:
I used a template language to generate the javascript variables I needed.
I'm not a PHP programmer but I'm going to give you the idea, let me now if works. The following isn't php code, is just for ilustrate.
<?php
<script type="text/javascript" ... >
SOME_VARIABLE = "{0}".format(php_function()) // php_function resolve the value you need
</script>
?>
The I use SOME_VARIABLE in my scripts.
Please specify your onreadystatechange event handler before calling open and send methods.
You also should make your choice between GET and POST method for your request.
If you want to popup your message only when your request object status is OK (=200) and readyState is finished whith the response ready (=4), you can write :
request.onreadystatechange = function() {
if (request.readyState==4 && request.status==200) {
var phpMessage = request.responseText;
alert(phpMessage);
}
};

Categories

Resources