This question already has answers here:
How to replace the entire html webpage with ajax response?
(6 answers)
How to replace innerHTML of a div using jQuery?
(14 answers)
Closed 3 years ago.
In index.html, I'm getting a value stored in localStorage:
<script>
function checkChannel() {
if (localStorage.getItem('channel')) {
const channel = localStorage.getItem('channel');
const request = new XMLHttpRequest();
request.open('POST', '/convert');
// Add data to send with request
const data = new FormData();
data.append('channel', channel);
// Send request
request.send(data);
}
}
</script>
</head>
<body onload="checkChannel()">
.
.
.
This works fine. It is routed to the code below in application.py. The debugger hits the first line in convert() below, so I know it's getting there.
#app.route("/convert", methods=["POST"])
def convert():
channel = request.form.get("channel")
channel_messages = channels_dict[channel]
return render_template("channel.html", channel=channel, channel_messages=channel_messages)
However, channel.html is not being rendered. Instead, it stays on the same page. What am I doing wrong here? I can give more details if needed.
You need to define a request.onload() function. This function will be called after the response is received. so your JS code will be similar to this:
function checkChannel() {
if (localStorage.getItem('channel')) {
const channel = localStorage.getItem('channel');
const request = new XMLHttpRequest();
request.open('POST', '/convert');
// Add data to send with request
const data = new FormData();
data.append('channel', channel);
// Send request
request.send(data);
// 4. This will be called after the response is received
request.onload = function() {
if (request.status != 200) {
// analyze HTTP status of the response
alert(`Error ${request.status}: ${request.statusText}`);
// e.g. 404: Not Found
} else { // show the result
$('body').html(request.response)
}
};
}
}
Please note that you can replace $('body').html('some content') by $('div').html('some content') or $('#some-id').html('some content') based on channel.html file content.
Please find this example.
Related
We want to send a boolean value from python to javascript so we can use it in our html website.
We tried using sockets but thats too complicated for us. Our next thought was to use an api and we know how to get information from an api using javascript. What we want to do is post a python boolean value to an api, and then get the boolean value from the api using javascript.
But we don't know how to do so.
We are using a raspberry pi for all our code and a hardware-button which returns true in python when pressed.
We are currently testing code we found from https://healeycodes.com/javascript/python/beginners/webdev/2019/04/11/talking-between-languages.html
But this code doesnt work for us.
We are also using pycharm as our workspace, is this a problem?
Our current code in javascript:
const request = new XMLHttpRequest();
request.open("GET", url, true);
request.onreadystatechange = function() {
if (request.readyState === 4 && request.status === 200) {
success(JSON.parse(request.responseText));
}
};
request.send();
setInterval(get("button-status.json", receiveStatus), 3000);
}
function receiveStatus(response) {
if (response.status !== status) { // only do something if status has changed
status = response.status;
console.log('button status is now', status);
}
}
let status;
// checks every 100ms
get()
Our python code we're using for testing:
import random
import json
import time
button_status = False
path = (r"C:\Users\Sam\Desktop\pythonProject\pythonflask\emplates") # replace with your actual path
def save_button_status():
with open(path + "/button-status.json", "w") as f:
json.dump({'status': button_status}, f)
while True :
value = random.randrange(1, 10)
if ( value <= 5) :
button_status = True
save_button_status()
time.sleep(3)
else :
button_status = False
save_button_status()
time.sleep(3)
print(button_status)
Javascript within a webpage cannot directly run a Python script on your computer or read information from a local terminal. What you could do is have your Python program output a small json file to your localhost folder which is overwritten when the button is pressed or released, like this:
import json
button_status = False # assuming it is initially off
path = "path/to/your/localhost/folder" # replace with your actual path
def save_button_status():
with open(path + "/button-status.json", "w") as f:
json.dump({'status': button_status}, f)
# Then call save_button_status() whenever the status changes
Then in your javascript, set an interval to periodically call a function that gets this json file and does something based on the value if it has changed:
function get(url, success) {
//--- Get JSON data at the given URL and call `success` if successful
const request = new XMLHttpRequest();
request.open("GET", url, true);
request.onreadystatechange = function() {
if (request.readyState === 4 && request.status === 200) {
success(JSON.parse(request.responseText));
}
};
request.send();
}
function receiveStatus(response) {
if (response.status !== status) { // only do something if status has changed
status = response.status;
console.log('button status is now', status);
}
}
let status;
let interval = setInterval(() => get("button-status.json", receiveStatus), 100); // checks every 100ms
There may be some lag as your local server updates the file.
You can try to set up a SQL Database. Write a SQL statement in Python to receive your boolean. After that make a PHP script on your Web server to receive the SQL data. Then sent a request to the URL of the PHP script using an XHTTP JavasScript request.
I'm new to using nodejs and javascript so I'm sorry if I'm just doing something obviously wrong. I have a nodejs app I'm running and serves a html page. That html page can send Post requests using XMLHttpRequest. The request goes though and my node app calls the function that my request is meant to invoke. The problem is I want to get some data back from that request so I am trying to get that from the response to the request. The issue is I am getting an empty response and I do not know why.
Here is my request.
function SendCachedTriangulation(){
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById('responseLog').textContent = "sent triangulation: " + this.response;
}
};
xhttp.open("Post", "/sendCachedTriangulation");
xhttp.setRequestHeader("Content-type", "application/json");
var text = '{ "data" : ' + '{ "someData":"' + '1' + '" } }';
xhttp.send(text);
return false;
}
The result I get from this is response is empty. It does update the element I am trying to update but it just says "sent triangulation: ".
On the nodejs side this is my code.
router.post('/sendCachedTriangulation', (req, res, next) => {
client.SendCachedTriangulation(() => {
res.status(200)
;}, req.body
);
res.status(200).message = "sent triangulation";
res.send();
});
Which this seems to be calling my function to send cached triangulation properly i just don't get that "sent triangulation" message.
What do I need to change to display that message in my HTML page?
Actually I understood your snippet. I also understand that is complicated at first time with Node, because is everything Javascript. Let me explain: in your HTML, think the request is OK, but actually have, let's say, two files: HTML file, that performs the request, and the node HTTP server, that responds the request. So I mean something like:
// /server/app.js
router.post('/sendCachedTriagulation', (req, res, next) => {
res.status(200).send("sent triangulation")
})
// /client/index.html
client.SendCachedTriangulation(/* do stuff */)
I was going through the following article :
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Fetching_data
Here , the concept of AJAX is being illustrated however , for simple illustration ,instead of connecting to the server ,the content is being fetched from the system which has the browser in it .
So in the following code lines from the above mentioned link :
var url = verse + '.txt';
var request = new XMLHttpRequest();
request.open('GET', url);
Here a GET verb is to fetch the contents of the file in the local system and no server is present there .
Similarly , by using javascript and in the absence of a server
can we add some parameters to GET or POST verb and run a code in the local system which processes these parameters and sends an output .
Like :
var url = 'verse + '.txt' + '?' 'name = ' + 'vim' ; //Adding parameters
and there will be some javascript file , which takes these parameter "name "
and returns it in uppercase , like "VIM " .
Can we do anything like that using Javascript only (not nodejs or anything that sets up a server " ) without server listening ?
To achieve the requirement you can use Chromium or Chrome browser launched with --allow-file-access-from-files flag set.
fetch() does not permit requesting local files having file: protocol, though XMLHttpRequest() does. fetch() does allow requesting data URL and Blob URL.
For
some javascript file , which takes these parameter "name " and returns
it in uppercase , like "VIM "
Worker can be used to get the contents of a local file, manipulate the content, then postMessage() can be called to communicate with main thread.
For example
worker.js
onmessage = e => {
// do stuff
let url = new URL(e.data);
let [[,param]] = [...url.searchParams]; // get query string parameter `'vim'`
let request = new XMLHttpRequest();
request.open('GET', 'file:///path/to/local/file' /* e.data */);
request.onload = e => {
console.log(request.responseText); // `setTimeout()` can be inside `load` handler
}
request.send();
// asynchronous response
setTimeout(() => {
// set `data URL` that `fetch()` will request
postMessage(`data:text/plain,${param.toUpperCase()}`);
}, Math.floor(Math.random() * 2000));
}
At console or within a script
const localRequest = async(url) => {
const request = await fetch(await new Promise(resolve => {
const worker = new Worker('worker.js');
worker.onmessage = e => {
resolve(e.data);
worker.terminate();
}
worker.postMessage(url);
}));
const response = await request.text();
console.log(response);
}
localRequest('file:///verse.txt?name=vim');
I am a complete beginner with REST API and I could not figure out how I am to proceed.
I installed Postman and was successfully able to get the Token, but I am not sure how to send the raw XML payload in javascript.
<tsRequest>
<credentials name ="XXX" password="YYY" >
<site contenturl = "" />
</credentials>
</tsRequest>
I have :
httpRequest.open('POST', 'http://MY-SERVER/api/2.4/auth/signin', false);
httpRequest.setRequestHeader("Content-type", "application/xml");
Not sure how to add the xml payload. I have access to a Tableau Server(MY-SERVER) and everything.
Any help would be greatly appreciated!
Thank you!
You are getting closer, you just need to use the send method to send your XML: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/send
Just make sure that your XML is properly encoded in javascript when you're inputting it. So if you are using double quotes inside your XML, make sure you have single quotes to declare your string in javascript (e.g.) var data = '<credentials name="XXX" >';
Related: Send POST data using XMLHttpRequest
In addition to #AnilRedshift answer, here's the functioning code:
login_details=[];
function getToken() {
var url = "http://yourServerAddress/api/2.0/auth/signin";
var params = "<tsRequest><credentials name='Username' password='UserPassword' ><site contentUrl='' /></credentials></tsRequest>";
return zuo = new Promise(function(resolve,reject){
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.withCredentials = true;
xhr.onload= function(){
if (this.status === 200) {
var parsed_xml = JSON.parse(JSON.stringify(x2js.xml_str2json(xhr.responseText)))
login_details.push(parsed_xml.tsResponse.credentials._token); login_details.push(parsed_xml.tsResponse.credentials.site._id);
resolve(login_details);
}
}
xhr.onerror=reject;
xhr.send();
})
}
function getWorkbooks(){
var url = "http://serveraddress//api/2.3/sites/"+login_details[1]+"/workbooks?pageSize=1000";
return zuo = new Promise(function(resolve,reject){
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.setRequestHeader("X-Tableau-Auth",login_details[0]);
xhr.onload= function(){
if (this.status === 200) {
var workbooks = JSON.parse(JSON.stringify(x2js.xml_str2json(xhr.responseText)))
for (var f=0;f<workbooks.tsResponse.workbooks.workbook.length;f++){
if(workbooks.tsResponse.workbooks.workbook[f].project._name=="Default"){
workbooks_list.push(workbooks.tsResponse.workbooks.workbook[f]._id)
}
resolve();
}
}
}
xhr.onerror= function(){
console.log(xhr.responseText);
}
xhr.send();
})
}
Invoke the code with:
getToken()
.then(function(login_details){
console.log(login_details[0]+"/"+login_details[1]);
})
.then(function(){
getWorkbooks();
})
getToken() function gets the login token which has to be used in all subsequent calls.
getWorkbooks() fetches all dashboards in 'Default' project but this kind of request can be used for all GET type requests.
Please note that this approach uses hardcoded values for password and username which is generally not the best practice. It would be way better to use server side scripting or encrypting (better but still with flavs).
You can find whole step by step tutorial and running code here:
http://meowbi.com/2017/10/23/tableau-fields-definition-undocumented-api/
This question already has answers here:
How to return AJAX response Text? [duplicate]
(2 answers)
Closed 9 years ago.
I use pageinit to load page. I call an XMLHttpRequest to send and get request to PHP programs on Linux, using RESTful API on server side. The server side accept an array I send to it and echo an JSON back. It all work well. However, HTTP_GET functions returns back to page and displays content before it finished and got a response from server.
How can I prevent it from going back before it responded?
pageinit
$(document).on("pageinit","#quote_open1",function(){
alert('pageinit quote_open1');
openPage(); });
openPage
function openPage(url, jsontest){
var jsonResponse=HTTP_GET( url, jsontest);
alert('!!!!!!!!!!!!!!!!-->'+jsonResponse);
}
HTTP_GET
function HTTP_GET( url, jsonToSend){
alert('START HTTP_GET');
var jsonResponse;
//send get request to server
xhr = new XMLHttpRequest();
xhr.open("GET",url+"jsonToSend",true); //open server connection
xhr.send();//this is where json string will be sent out
//
//this function send
xhr.onreadystatechange = function()
{
if (xhr.readyState == 4) //read server response
{
alert(xhr.readyState);
jsonResponse=xhr.responseText;
alert("!!!jsonResponse="+jsonResponse);
alert("!!!xhr.responseText"+xhr.responseText);
return "server returned a response 1"; //RETURNS this all the time
}
};
alert('END HTTP_GET');
if (xhr.readyState == 4) return "server returned a response 2"; //want to return this when leaves this function
return "stil in progress returns before it's finished";
};
(this 3 functions are in different js)
Thanks.
what you miss here is the fact that xhr is asynchrone, so your function HTTP_GET returns before the request is done.
You could use a callback function like this :
$(document).on("pageinit","#quote_open1",function(){
console.log('pageinit quote_open1');
openPage(); });
function openPage(){
var doTheJob = function(jsonResponse){ console.log('jsonResponse : '+jsonResponse); }
HTTP_GET( url, doTheJob);
}
function HTTP_GET( url,callBackFunc){
console.log('START HTTP_GET');
var jsonResponse;
//send get request to server
xhr = new XMLHttpRequest();
xhr.open("GET",url,true); //open server connection
xhr.onreadystatechange = function()
{
if (xhr.readyState == 4) //read server response
{
callBackFunc(xhr.responseText);
}
};
xhr.send();//this is where json string will be sent out
//
console.log('END HTTP_GET');
};