Using flask and ajax - javascript

I'm serving a web app made with flask. I just added a feature to make a geocoding request to google using ajax. So, pushing a button calls this function in loc_gm.js:
$(function() {
$('#geo_google').click(function() {
$.ajax({
url: 'geo_gm',
data: $('form').serialize(),
type: 'POST',
success: function(response) {
response = JSON.parse(response)
$('#Lat').val(response['lat']);
$('#Long').val(response['lng']);
},
error: function(error) {
console.log(error);
}
});
});
});
And this is the code in view.py:
#app.route('/geo_gm', methods=('GET', 'POST'))
def geo_gm():
calle1 = request.form['calle1']
calle2 = request.form['calle2']
altura = request.form['altura']
if calle1 and calle2:
address = '{}+y+{},+CABA,+AR'.format(calle1, calle2)
elif calle1 and altura:
address = '{}+{},+CABA,+AR'.format(calle1, altura)
url = 'https://maps.googleapis.com/maps/api/geocode/json?address={}&key={}'.format(address, GOOGLE_KEY)
response = requests.get(url)
result = response.json()
return json.dumps(result['results'][0]['geometry']['location'])
This works in my local machine ( I get the coordinates I want from Google), but when I upload it to the server (Digital Ocean), I get this error in the javascript console:
POST http://192.xx.xx.xxx/geo_gm 404 (NOT FOUND)
Being that IP address the one where my app is hosted.
I know this must be a silly mistake I'm making, but I can't figure it out.
Thanks!

Well, I finally found a workaround.
I added in the html file this:
<input type="hidden" id="geo-gm" name="variable" value="{{ url_for('geo_gm') }}">
That way I can have the relative path to geo_gm function. And then in the js file:
$.ajax({
url: $('#geo-gm').val(),
I did it this way because using {{ url_for('geo_gm') }} directly in the js file didn't work.
Maybe it's not the best way to do it, so if someone has a better way I'll be happy to hear it.
Thanks everybody.

Related

An AJAX request to get the new upload URL

I'm using Google App Engine for a backend service and I'm trying to upload a file using an AJAX post and their Blobstore API. I got that part working. If you are not familiar with the service, is quite simple. Blobstore API uploads is a two step process: You need to get an upload url and then upload into that url.
Now, I'm implementing an editor, medium.com-like.
The thing is this plugin needs an endpoint for the upload. As my endpoint is not static and I need to update that URL each time, I have prepared an API in the backend that responds with a JSON file with that URL. I'm trying to do an AJAX request to get that URL but I'm getting an error, as the POST request is done to bad url.
This is the POST requet:
INFO 2014-10-19 08:58:22,355 module.py:659] default: "POST /admin/%5Bobject%20Object%5D HTTP/1.1" 200 2594
An this is my Javascript code:
function getURL(callback) {
return $.ajax({
type: "GET",
url: "/admin/upload_url",
dataType: "json",
success: callback
});
};
$('.editable').mediumInsert({
editor: editor,
addons: {
images: {
imagesUploadScript: getURL().done(function(json){return json['url']})
},
embeds: {
oembedProxy: 'http://medium.iframe.ly/api/oembed?iframe=1'
}
}
});
I guess I'm doing something wrong with the AJAX return, but if I console.log it I get the result I want. I've read this answer and try to apply it, but I didn't manage to get it working.
Thanks for your time and your help ! :)
If someone ever has the same problem this is the way I solved it. If you are reading this and you now a better one, please, every help is appreciated.
var url; // Set a global variable
// Define the AJAX call
function AJAXURL() {
return $.ajax({
type: "GET",
url: "/admin/upload_url",
success: function(response){
// Sets the global variable
url = response['url'];
}
});
};
// Gets a first upload URL doing an AJAX call while everything keeps loading
AJAXURL();
$('#editable').mediumInsert({
editor: editor,
addons: {
images: {
imagesUploadScript: function getURL() {
// makes a request to grab new url
AJAXURL();
// But returns the old url in the meanwhile
return url;
}
},
embeds: {
urlPlaceholder: 'YouTube or Vimeo Link to video',
oembedProxy: 'http://medium.iframe.ly/api/oembed?iframe=1'
}
}
});

400 Bad Request error when when moving application from local to web server

I have a pyramid application that runs perfectly on a local server, but when I move it over to a web server (Dreamhost), I get the following error:
400 Bad Request:
Bad request (GET and HEAD requests may not contain a request body)
The code in question is the following ajax in Javascript:
function summary_ajax(sName){
$.ajax({
type: "POST",
url: "summary",
dataType: "json",
data: {
'ccg_name': sName,
},
async: false,
success: function(data) {
//alert("In ajax success function") <----------- This never executes
lValues = data.lValues;
lLabels = data.lLabels;
},
});
};
return (lValues, lLabels);
And is handled in views.py:
#view_config(route_name="ccg_map_summary_ajax",renderer="json")
def ccg_map_summary_ajax(self):
sCCG = self.request.POST.get('ccg_name')
fData = open('pyramidapp/static/view_specific_js/ajax_summary_data.js')
dData = json.load(fData)
lLabels = dData[sCCG].keys()
lValues = dData[sCCG].values()
return {
'lLabels' : lLabels,
'lValues' : lValues,
}
I did some testing by placing alert() functions (its slow, because the server only reloads the script every so many minutes), and everything executes fine except for alerts in the ajax call. So it seems that either the post fails, or something goes wrong in the view. Any ideas?
So is there something in this code that works in my local server (in Pyramid) but breaks down in the web server (Dreamhost)?
The file structure is the same in the local and web server. I don't see why it shouldn't, but will fData still open the file for reading?
For anyone else out there, I found the problem:
The path I specified above was a relative path that worked on my system but not on the server because the working directories are obviously different. So instead of using a relative path, I just changed the script to have the correct absolute path.
To find the current working directory path, just enter pwd into terminal.

How can i receive data from external url using json?

Recently i am learning json to create apps.I have a doubt in a Json , php based chat system .
In this , the code work fine for same origin policy.But for sending and receiving data from external url, it successfully sends data to external php.But not receiving any data from server.I search in internet to solve this problem , and found jsonp as alternative. I tried jsonp , but i m not sure if am correct because i am new to ajax itself.
Please don't mis understand my question.I want to load a index.html file from localhost , when i send request to external url (anysite.com/xx/ajax.php) .It process and returns the data back to index.html.But the problem is my data is sended finely and processed on the server but it doesn't return to remote file.But it works fine for same server.
$.tzPOST = function(action,data,callback)
{
$.post('http://anysite.com/xx/ajax.php?action='+action,data,callback,'json');
}
$.tzGET = function(action,data,callback){
$.get('http://anysite.com/xx/ajax.php?action='+action,data,callback,'json');
}
please help me with a code.
You cant receive JSON from external web by JavaScript, because of the policy.
But you can do AJAX request on your PHP file and there you can get the JSON by file_get_content http://cz2.php.net/file_get_contents function.
For using(working) with jsonp, u can take ready solution jquery-jsonp
from GitHub.
Example of using (by you question):
$.tzGET = function(action,data,callback){
var url = 'http://anysite.com/xx/ajax.php?action='+action;
$.jsonp({
type: 'GET',
url: url,
callbackParameter: callback,
dataType: 'jsonp',
data: data,
timeout: 10000,
success: function(json){
alert('success')
},
error: function(){
alert('error')
}
});

AJAX Post to store JSON with Python and javascript

I have been having problems with getting AJAX to post JSON correctly. The application is intended to be hosted on Google App Engine. But what I have does not post data.
Python
mainPage = """
<html>
html is included in my python file.
</html>
"""
class JSONInterface(webapp2.RequestHandler):
def post(self):
name =self.request.get('name')
nickname =self.request.get('nickname')
callback = self.request.get('callback')
if len(name) > 0 and len(nickname) >0:
newmsg = Entry(name=name, nickname=nickname)
newmsg.put()
if len(name)>0:
self.response.out.write(getJSONMessages(callback))
else:
self.response.out.write("something didnt work")
def get(self):
callback = self.request.get('callback')
self.response.out.write(getJSONMessages(callback))
This handler is meant to handle the Ajax calls from the web app. I am unsure if I need javascript to be associated with my main page in order to do so, as I haven't found information on it yet with my searches.
Javascript
$(document).ready( function() {
$("#post").bind('click', function(event){
var name = $("#name").val();
var nickname = $("#nickname").val();
postData = {name: name, nickname: nickname, callback: "newMessage"};
$.ajax({
type: "POST",
url: "http://localhost:27080/json",
data: postData,
dataType: "json",
done: function() {
// Clear out the posted message...
$("#nickname").val('');
},
fail: function(e) {
confirm("Error", e.message);
}
});
// prevent default posting of form (since we're making an Ajax call)...
event.preventDefault();
});
The Javascript for the post
Can someone advise me on how I could resolve the problem I am having. Thanks for the time and help.
Did you ask the same question yesterday and then delete it? I swear I just answered the same question.
You're not sending your data as a JSON string. If you want to send as JSON, you need to encode data as a JSON string, or else you're just sending it as a query string.
data: JSON.stringify(postdata),
HOWERVER, your request handler is actually processing the request properly as query string instead of JSON, so you probably don't want to do that.
For starters, the ajax call is pretty close. The full path
"http:://localhost:27080/json"
is not necessary, the relative path will work, but that is not the problem.
Your callback, as it stands, will work as 'success':
success: function(response) {
alert(response);
// Clear out the posted message...
$("#nickname").val('');
}
However, this callback is being phased out in favor of other methods. 'Done' should be chained like so:
$.ajax({
type: "POST",
url: "/json",
data: postData,
dataType: "json"
}).done(function(data){
console.log(data);
});
Also, there might be problems on the server. If you use some logging, you will see that the data is indeed being sent to the server.
import json ## we'll get to this below
import logging
class JSONInterface(webapp2.RequestHandler):
def post(self):
name = self.request.get('name')
logging.info(name) ## will print the value of 'name'
Unless your python function getJSONMessages(callback) is returning a json object, your callback will not be called, even after you add the response parameter.
In your python code:
import json
import logging
class JSONInterface(webapp2.RequestHandler):
def post(self):
callback = self.request.get('callback')
logging.info(callback) # will print correctly
self.response.out.write(json.dumps(callback))
Using the json.dumps method encodes the passing object to json, which is what your ajax object is looking for.

How to get content type of a given url inside Javascript?

I want to know the content type of a given url input by the user inside my Javascript code. Actually, I have a drop-down list (html,csv,xls etc.) and I want to make it so when the user inputs an url, I want to detect the type of the content of the url and based on this type I want to set the value of my drop-down list (html,csv,xls etc.). I know, I can get the content type using Ruby like this :
require 'open-uri'
str = open('http://example.com')
str.content_type #=> "text/html"
or, also, I could use curl to get the content and then parse it to know the content type. But, I need to do this inside my Javascript code because of my need explained above. Any thought ?
EDIT_1 :
I tried this code in my javascript :
$("#wiki_form_url").change(function(){
$.ajax({
type: "GET",
url: "content.rb",
data: {
// input_url: $("#wiki_form_url").val()
},
dataType: "html"
}).done(function (data) {
// `data` contains the content-type
alert('Success !!!');
}).fail(function () {
alert("failed AJAX call");
});
});
I have a ruby script content.rb inside which I do :
require 'open-uri'
str = open('http://www.ofdp.org/benchmark_indices/25')
str.content_type
But, it does not seem to work. I am getting Ajax failure. May be it's because of url path of the script content.rb ? How should I specify a script path here ? (Relative or absolute)
The same origin policy prevents you from using client side JavaScript to directly discover information about arbitrary URIs (URIs you control are a different story).
You'll need to get that information with another technology, such as your server side Ruby.
You could do this by simply submitting a form to the server and returning a new webpage to the browser.
If you don't want to leave the page, then you can pass the data using Ajax. There are no shortage of Ajax tutorials out there, here is a good one from MDN.
Here's an example of an AJAX call:
$(document).ready(function () {
$("#button_check").on("click", function () {
$.ajax({
type: "GET",
url: "Your URL",
data: {
input_url: $("#textbox_id").val()
},
dataType: "html"
}).done(function (data) {
// `data` contains the content-type
alert(data);
}).fail(function () {
alert("failed AJAX call");
});
});
});
Where your HTML is something like:
<input type="text" id="textbox_id" />
<input type="button" id="button_check" value="Submit" />
And your Ruby code would be something like:
require 'open-uri'
class TestController < ApplicationController
def index
req = open(params[:input_url])
render :text => req.content_type
end
end
I have never used RoR before, so I have no idea if this is right or works in the slightest. But it's what I could quickly conjure up when scrambling through several tutorials. It's simply the concept you seem to be looking for. You'll need to figure out how to map a URL to this method, and then update the AJAX option url to use that.
So in the Javascript code - in the done method, that means the whole AJAX request was successful and the data variable should contain the result from the Ruby code req.content_type.
Atlast I could figure out the whole thing with the great help of #Ian. Here is my completed code : In javascript file :
$("#wiki_form_url").change(function () {
$.ajax({
type: "GET",
url: "/wiki_forms/content",
data: {
input_url: $("#wiki_form_url").val()
},
dataType: "text"
}).done(function (data) {
// `data` contains the content-type
alert('Success');
console.log(data);
// alert(data);
}).fail(function () {
alert("failed AJAX call");
});
});
Inside my wiki_forms controller I created a new method named content :
def content
req = open(params[:input_url])
render :text => req.content_type
end
Then added a new route in routes.rb file :
get "/wiki_forms/content" => 'wiki_forms#content'
and used /wiki_forms/content as the ajax request url. And, everything is working nicely now.

Categories