Handle JSON events in Python - javascript

i have searched in google and on stackoverflow and could find a good answer.
i have that code on my HTML page that gets HTML output of python(i'm using jquery):
$.ajax({
type: "POST",
url: "getHTML.py",
success: function(response)
{
$('body').append(response);
}
});
python file looks like that:
baseHTML = "www.google.com"
user_agent = "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)"
headers = {"User-Agent": user_agent}
req = urllib2.Request(baseHTML, headers=headers)
forumHTML = urllib2.urlopen(req)
page = Soup(forumHTML)
for e in page.findAll('script'):
e.extract()
print 'Content-Type: text/plain\r'
print '\r'
print page
Every thing works and i'm happy, But... now i tried to add another JSON that sent by a button click event:
$('#GetByURL_button').on("click", function(){
$.ajax({
url: "getHTML.py",
type: "POST",
data: JSON.stringify({"newURL": "www.stackoverflow.com"),
dataType: "json",
success: function(response) {
alert(response);
}
});
});
and now i just don't know how to handle that event in python.
So just to be clear - i want python to have something like:
if user didn't ask for anything(via JSON) load default page,
if user asked for "stackoverflow"(via JSON) load www.stackoverflow.com
if user asked for "dog" load www.DogsAreCool.com.
tnx for the help :)

You didn't specify what framework or mechanism you're using to hook up Python scripts, and your sample doesn't show the script handling input at all.
So, let's assume you're using a mechanism that gives you the request body as stdin, like old-school CGI. You'd do something like this:
content = sys.stdin.read()
data = json.loads(content)
newURL = data.get('newURL')
if newURL == 'dog':
newURL = 'http://www.DogsAreCool.com'
elif not newURL:
newURL = defaultPageURL
response = urllib2.urlopen(newURL)
# ...

Two approaches:
your server send backs the correct URL via a normal http response (200 OK)
your ajax code sets window.location
your browser is happy to redirect
Second one:
your server sends a redirect response with correct location header.
your ajax request will follow the redirect and return the correct content.
your ajax inserts content in the DOM.

Related

Request to Google Apps Script URL for deployed WebApp produces 404 error

This issue is very similar to others (like Google Drive Page Not Found - Sorry, unable to open the file at this time for example) posted here. It's not exactly the same, but I do believe it has the same root issue illustrated in that post in that trying to submit a form to a Google App Script while logged into more than to 1 Google account causes /u/1 and/or /u/0 to be added to the script's URL thus producing a 404 Error.
This is using a standard Google account - not G-Suite.
I have a form on a website that submits to a Google Apps Script via AJAX. The script makes some API calls to create a Google Doc containing the data collected by the form.
HTML/Javascript:
<form>
<input type="text" name="full_name">
<input type="text" name="phone">
<input type="submit">
</form>
$('form').submit(function() {
var obj = $(this).serializeObject();
var gurl = "https://script.google.com/macros/s/AKfycbzmhaub3ojPARA-B-Y2uVC2BJZPaRvbgMwMTH9pd7R9aHuAD5M/exec";
$.ajax({
url: gurl,
type: "GET",
data: obj,
dataType: "jsonp",
success: function(data, status, xhr) {
console.log("success");
console.log(data);
});
});
GoogleScripts
function doGet(e) {
var params = e.parameters
var result = {};
try {
result = {
status: start(params),
msg: 'Success',
vals: formData,
rawVals: params,
errs: errors
}
} catch (f) {
result.error = f.toString();
}
return ContentService
.createTextOutput(e.parameters.callback + '(' + JSON.stringify(result) + ')')
.setMimeType(ContentService.MimeType.JAVASCRIPT);
}
Submitting the form while logged into more than 1 Google account in the same browser results in the following error in the console and the form does nothing:
jquery.js?ver=1.12.4-wp:4 GET
https://script.google.com/macros/u/1/s/AKfycbzmhaub3ojPARA-B-Y2uVC2BJZPaRvbgMwMTH9pd7R9aHuAD5M/exec?callback=jQuery112407830193282901534_1608623376571&s&full_name=Dave+Pe&phone=1111111111_=1608623376572
net::ERR_ABORTED 404
When I go to Network tab to view the request, the Header tab there shows the following:
Request URL: https://script.google.com/macros/u/1/s/AKfycbzmhaub3ojPARA-B-Y2uVC2BJZPaRvbgMwMTH9pd7R9aHuAD5M/exec?callback=jQuery112407830193282901534_1608623376571&s&full_name=Dave+Pe&phone=1111111111_=1608623376572
Notice the /u/1/ that have been inserted into the URL that are not present in the URL I pass to my $.ajax() call.
Most of the answers I've found for this issue say to just remove the /u/1/, but since I didn't add it in the 1st place, I don't know where I would remove it from.
Can anyone confirm that this seemingly known issue (of having the URL altered when logged into multiple Google accounts) is what is causing my problems? Any ideas as to how I can go about making my request to:
https://script.google.com/macros/s/AKfycbzmhaub3ojPARA-B-Y2uVC2BJZPaRvbgMwMTH9pd7R9aHuAD5M/exec
and not
https://script.google.com/macros/u/1/s/AKfycbzmhaub3ojPARA-B-Y2uVC2BJZPaRvbgMwMTH9pd7R9aHuAD5M/exec
?? or is there something more deeply wrong with the way I'm trying to use Google Scripts here?
My solution was to move the request from the client side to the server. I submit my form values to a server-side page via AJAX and then on that page, I make an HTTP request with cURL to my Google Apps Script (sending the form data in the body) and send the response back to the client.
Seems to be working... no issues I can think of but that doesn't mean they don't exist. If there are any holes to be shot in that approach, please feel free to unload.
Watered down...
JavaScript
$.ajax({
url: '/ajax-handler.php',
type: "POST",
data: obj
success: function(data, status, xhr) {
console.log("success");
console.log(data);
});
});
PHP
$vals = my_sanitize_func($_POST);
$url = GAS_URL;
$fields = $vals;
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, count($fields));
curl_setopt($ch,CURLOPT_POSTFIELDS, http_build_query($fields));
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);
// handle/format response;
$result = ...
print $result;
You can also do whatever you want this way.
Google App Script (Code.gs):
function doGet(e){
var action = e.parameter.action;
if (action=="sendSuccess"){
justSendSuccess(e);
}
}
function justSendSuccess(e){
var output = JSON.stringify({"result":"success"});
return ContentService
.createTextOutput(e.parameter.callback+"("+ output + ");")
.setMimeType(ContentService.MimeType.JAVASCRIPT);
}
JavaScript Part:
function callGoogleScript(){
console.log("Started");
var url = "https://script.google.com/macros/s/###SCRIPT_ID###/exec";
$.ajax({
crossDomain: true,
url: url,
data: {
"action":"setInfo"
},
method: "GET",
dataType: 'jsonp',
jsonp: "callback",
success: function(data){
console.log("SUCCESS!");
console.log(data);
}
});
}
I tried to run it (authenticated with a single account) and it seems to work. This error seems to happen because you are authenticated with multiple accounts. Also, it seems as it has already been documented at Google Issue Tracker (link to issue). If you want it to make it more visible, you can click the white star (☆) which tells google that you are affected by this issue.
As a side note, notice that the code you make will be executed by everyone as you. This code will have your privileges. Be very careful. Your account limits may also apply.

How to get a json response from yaler

I create an account with yaler, to comunicate with my arduino yun. It works fine, and i'm able to switch on and off my leds.
Then i created a web page, with a button that calls an ajax function with GET method to yaler (yaler web server accept REST style on the URL)
$.ajax({
url: "http://RELAY_DOMAIN.try.yaler.net/arduino/digital/13/1",
dataType: "json",
success: function(msg){
var jsonStr = msg;
},
error: function(err){
alert(err.responseText);
}
});
This code seem to work fine, infact the led switches off and on, but i expect a json response in success function (msg) like this:
{
"command":"digital",
"pin":13,
"value":1,
"action":"write"
}
But i get an error (error function). I also tried to alert the err.responseText, but it is undefined....
How could i solve the issue? Any suggestions???
Thanks in advance....
If the Web page containing the above Ajax request is served from a different origin, you'll have to work around the same origin policy of your Web browser.
There are two ways to do this (based on http://forum.arduino.cc/index.php?topic=304804):
CORS, i.e. adding the header Access-Control-Allow-Origin: * to the Yun Web service
JSONP, i.e. getting the Yun to serve an additional JS function if requested by the Ajax call with a query parameter ?callback=?
CORS can probably be configured in the OpenWRT part of the Yun, while JSONP could be added to the Brige.ino code (which you seem to be using).
I had the same problem. I used JSONP to solve it. JSONP is JSON with padding. Basically means you send the JSON data with a sort of wrapper.
Instead of just the data you have to send a Java Script function and this is allowed by the internet.
So instead of your response being :
{"command":"digital","pin":13,"value":0,"action":"write"}
It should be:
showResult({command:"analog",pin:13,value:0,action:"write"});
I changed the yunYaler.ino to do this.
So for the html :
var url = 'http://try.yaler.net/realy-domain/analog/13/210';
$.ajax({
type: 'GET',
url: url,
async: false,
jsonpCallback: 'showResult',
contentType: "application/json",
dataType: 'jsonp',
success: function(json) {
console.dir(json.action);
},
error: function(e) {
console.log(e.message);
}
});
};
function showResult(show)
{
var str = "command = "+show.command;// you can do the others the same way.
alert (str);
}
My JSON is wrapped with a showResult() so its made JSONP and its the function I called in the callback.
Hope this helps. If CORS worked for you. Could you please put up how it worked here.

POST Request PHP equivalent in AJAX / JQuery

I'm able to send some POST requests to a php file. On this php file, I use this to check if my POST request is what I want:
<?php
if(isset($_POST['message'])) {
// Some stuff here
}
?>
I would like to know if I can do the same thing in AJAX / JQuery ?
Not something like this:
<script>
$.post("page.php", $("form[name=addMessage]").serialize(), function(data) {
//Do something here
}).error(function() {
//error
})
</script>
EDIT:
I don't want to send POST request in AJAX / JQuery. I just want to check if I receive a POST request, send from another page.
Indeed, I send a POST request with a field named "message". And I my question is: Is it possible to check if the field "message" is set, but not in PHP, in AJAX / JQquery.
Thank you so much for your help.
Regards,
Lapinou.
If I understand what you are trying to do: No.
Do you want to just listen for an incoming request in Javascript without calling any Ajax-methods? This is not possible. Javascript needs to be told that "I am sending a request now, and I want a response". It is not possible to say "If any request is sent, deal with it here".
Think about it. How would this work? If Javascript would listen to any request incoming, how would it know the difference between an user submitting a form and you sending a request using Postman?
Also, once you load the website in your browser, this is said to be clientside. Everything that happens after that is bound to your computer and your instance of the website. Any request sent to the site would be sent to the server, not your browser.
An other way of doing a post is this:
$.ajax({
type: "POST",
url: "page.php",
cache: false,
data: "message=" + $(".msgBox").val(), //Or Json format { "message" : $(".msgBox").val() },
success: function(html){
$(dashboard_id).html(html);
}
});
Try this:
$("form[name=addMessage]").submit(function(e) {
e.preventDefault();
$.post("page.php", $(this).serialize(), function(data) {
//Do something here
}).error(function() {
//error
})
});
*Update
As per your comment you want to check POST value using JavaScript / jQuery, I don't think so you can access POST data using JavaScript / jQuery. But you want to mix php then you can do something like this
var post = '<?php json_encode($_POST); ?>';
if (post.message !== undefined) {
}
You have to put var post = '<?php json_encode($_POST); ?>'; in a php file

Strange $.post() AJAX error when parsing JSON

I am facing this strange error in using $.post.
works
$("#add-video").click(function(){
var url = $("#new-video-url").val();
$('#loader').show();
$.post( base_url + "forms/coach/get_url.php", { url:url, base_url:base_url }, function(data){
alert(data);
$('#loader').hide();
});
});
The above piece of code, shows me the json array I am receiving using a php file, and also shows the title field here, and hides the loader image.
But when I alert(data.title), it shows me undefined. More over, when I add datatype 'json' to $.post,
doesn't work
$("#add-video").click(function(){
var url = $("#new-video-url").val();
$('#loader').show();
$.post( base_url + "forms/coach/get_url.php", { url:url, base_url:base_url }, function(data){
alert(data);
$('#loader').hide();
}, "json"); //Added datatype here.
});
This neither alerts anything nor does it hide the loader image. I also tried,
$("#add-video").click(function(){
var url = $("#new-video-url").val();
$('#loader').show();
$.post( base_url + "forms/coach/get_url.php", { url:url, base_url:base_url }, function(data){
jQuery.parseJSON(data);
alert(data.title);
$('#loader').hide();
});
});
The above one too neither alerts anything nor does it hide the loader. And then I tried this one too that did nothing.
$("#add-video").click(function(){
var url = $("#new-video-url").val();
$('#loader').show();
$.post( base_url + "forms/coach/get_url.php", { url:url, base_url:base_url }, function(data){
jQuery.parseJSON(data); //tried without this too.
alert(data['title']);
$('#loader').hide();
});
});
The strangest thing is that I have previously used json as I have shown in the 2nd script(out of 4), and that works normally. My JS console too doesn't show any errors or warning. What am I doing wrong here? How do I access the title field of data?
If this helps, here is how I send the json array,
$json = array("title" => $title, "embed" => $embed, "desc" => $desc, "duration" => $duration, "date" => $date);
print_r(json_encode($json));
I would really appreciate if someone can point out the error and tell me why my scripts are failing, similar functions worked in other js file.
here is my data, that is returned by server,
{"title":"Sunn Raha Hai Na Tu Aashiqui 2 Full Song With Lyrics |
Aditya Roy Kapur, Shraddha Kapoor","embed":"\r\t\t\t\t\t\r\t\t\t\t\t</param></param>\r\t\t\t\t\t</param>\r\t\t\t\t\t\r\t\t\t\t\t</embed></object>","desc":"Presenting
full song \"Sun Raha Hai Na Tu\" with lyrics from movie \"Aashiqui 2\"
produced by T-Series Films & Vishesh Films, starring Aditya Roy Kapur,
Shraddha Kapoor in voice of Ankit Tiwari. \n\nSong: SUNN RAHA
HAI\nSinger: ANKIT TIWARI\nMusic Director: ANKIT TIWARI\nAssistant Mix
Engineer - MICHAEL EDWIN PILLAI\nMixed and Mastered by ERIC PILLAI
(FUTURE SOUND OF BOMBAY)\nLyrics:SANDEEP NATH\nMovie: AASHIQUI
2\nProducer: BHUSHAN KUMAR KRISHAN KUAMR Producer: MUKESH BHATT
\nDirector: MOHIT SURI\nMusic Label: T-SERIES\n\nBuy from iTunes -
https://itunes.apple.com/in/album/aashiqui-2-original-motion/id630590910?ls=1\n\nEnjoy
& stay connected with us!! \n\nSUBSCRIBE T-Series channel for
unlimited entertainment\nhttp://www.youtube.com/tseries\n\nCircle
us on G+ \nhttp://www.google.com/+tseriesmusic\n\nLike us on
Facebook\nhttp://www.facebook.com/tseriesmusic\n\nFollow
us\nhttp://www.twitter.com/_Tseries","duration":"391","date":"2013-04-03"}
Edit
This worked suddenly.. :o
$("#add-video").click(function(){
var url = $("#new-video-url").val();
$('#loader').show();
$.post( base_url + "forms/coach/get_url.php", { url:url, base_url:base_url }, function(data){
alert(data.desc);
console.log(data.desc);
$("#loader").hide();
}, "json");
});
In comments, you mention that this AJAX corresponds to a YouTube API.
YouTube's blog announced in 2012 that they would support CORS, which uses server-side header flags that compatible browsers interpret as permitting requests that would otherwise be prohibited by browser security Same-Origin-Policy.
Assuming, as you say, the first example worked, the first issue was "Why did (a subsequent) alert(data.title) fail? (my edit) ". If you type alert(data.title) in the console, it will fail because the scope of data is the callback function where it is defined as a parameter, and in the global scope data is undefined. If you try to pass data back to the global scope somehow, it can still be undefined because $.post returns immediately, before the data has been fetched, and merely queues a request and sets the callback function you supply to handle the reply.
The second example, which explicitly sets the $.post dataType parameter to 'json', may fail with CORS based API because the mime types for json are not allowed to be sent up to the server as Content-Type: for a simple CORS request, and $.post will as far as I know only do simple requests without preflight. $.ajax can possibly do the more complex requests if correctly applied.
The work around to keep using $.post is not to use json as the expected data type, send requests up as form data, the server may send you back json anyway if that is what the API says will happen, which can be verified while testing the code.
From https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS
Simple requests
A simple cross-site request is one that:
Only uses GET, HEAD or POST.
If POST is used to send data to the
server, the Content-Type of the data sent to the server with the HTTP
POST request is one of application/x-www-form-urlencoded,
multipart/form-data, or text/plain.
Notice that application/json did not make the list of what Content-Type is permissible in a simple CORS request.
See also A CORS POST request works from plain javascript, but why not with jQuery?
Use ajax as
$.ajax({
url:url,
type:'post',
dataType:'json',
success:callback
})
With this type you can set lots of parameter in low level.
With datatype attribute jQuery parses JSON and send data as callback function.
I think you have to replace all single \ with double '\' to feed it to JSON.parse.

Reading byte array response from rest using Javascript

I have a rest url http://server1:8080/platform/collections/123-456-789 which returns an HTML file as a byte array.
How can I get the byte array response using Javascript or jQuery running in server2. I tried
jQuery.ajax({
url: "http://server1:8080/platform/collections/123-456-789",
type: "GET",
dataType: "html",
crossDomain: true,
username: "abcd",
password: "abcd",
async: true,
success: function(data) {
alert("1");
alert(data);
},
error: function (xhr, ajaxOptions, thrownError) {
alert("error"+xhr.responseText);
alert("error"+thrownError);
}
});
I don't go into the success method. How can I get the byte array response successfully?
Edit:
Even anyother way to get byte array responce using javascript or jquery is also appreciated
For several servers (with different domains) you need to enable CORS to allow cross-domain ajax requests. It should be possible as both servers are under your control.
On how to receive binary data with jQuery (which is currently not possible), see http://blog.vjeux.com/2011/javascript/jquery-binary-ajax.html
CORS is the newer way to go, but jsonp may be a bit easier...
With JSONP, you will need to wrap your file on server1 in some sort of script so you can set the content-type header to javascript and then JSONencode the file and write it to the response. This could be done in a couple of lines in PHP or server side javascript; you'll want the script to end up returning a "javascript file" containing something like this:
document.getElementById('content-holder').innerHTML="<html>this is my file</html>";
On the client (your static html page served from server2), you can then just place your content holder:
<div id='content-holder'></div>
and then a script to pull in content from server1:
<script type="text/javascript">
var getXsS = function(url)
{
var ss = 's' + 'cr' + 'ip' + 't';
var cst = document.getElementsByTagName(ss)[document.getElementsByTagName(ss).length-1];
var ts = 1*new Date();
var e = document.createElement(ss);
e.async=1;
var tsstr = '_ts1_='+ts;
if((''+url).indexOf('?')==-1){tsstr='?'+tsstr;}else{tsstr='&'+tsstr;}
var url2 = url+tsstr;
e.src=url2;
cst.parentNode.insertBefore(e,cst);
};
getXsS('http://server1:8080/platform/collections/123-456-789');
</script>
Note that if server1 is using SSL then server2 must be using SSL also.

Categories

Resources