AJAX Python Call Definition [closed] - python

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I want to call a definition that is located in Python with a parameter, using AJAX. The web framework I'm using is Flask.
In my test.py file:
def example(param):
In my JS file
$.ajax({
type: 'POST',
url: "test.py"
//pass param here?
});

$.ajax({
type: 'POST',
url: "test.py"
data: {
param: param
}
});
make sure to include your CSRF token. You can learn more about it here http://flask.pocoo.org/snippets/3/
you can add this to your js code.
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});

Related

Can't send/receive a header with axios and python

I`m trying to send custom headers in a post request with axios in the following way:
const onSubmit = async (data) => {
const token = await getAccessTokenSilently();
console.log(token);
const header = {
headers: {
'Authorization': `Bearer ${token}`
}
};
const body = {
source: "website",
user_id: user.sub,
message_category: "crypto",
message_text: data,
};
console.log(body);
axios
.post(serverUrl + "messages/post_message", body, header)
.then((res) => {
// setPosts(res.data.messages);
console.log(res);
})
.catch(function (error) {
// handle error
console.error(error);
});
};
But in my python cherrypy server I`m not getting the custom headers at all. although I do receive it in Acess-Control-Request-Headers as titles without the data.
debugging: auth = cherrypy.request.headers in python:
PS: Sending headers via postman works normally.
Considering that your API is working correctly (you might recheck that as well). See if this works for you:
const onSubmit = async (data) => {
const token = await getAccessTokenSilently();
const options = {
headers: {
'Authorization': `Bearer ${token}`
},
body: {
source: "website",
user_id: user.sub,
message_category: "crypto",
message_text: data,
}
};
axios
.post(serverUrl + "messages/post_message", options)
.then((res) => {
// setPosts(res.data.messages);
console.log(res);
})
.catch(function (error) {
// handle error
console.error(error);
});
};

How to send next() in a callback function

Here i want to send the next() when my data is received from the python script but i am getting Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client.
const {PythonShell} = require('python-shell');
module.exports = (req, res, next)=>{
let myPythonScriptPath = 'encrypt.py';
const pyshell = new PythonShell(myPythonScriptPath);
let path = req.file.path;
pyshell.send(path);
pyshell.on("message", function(data){
console.log(data);
req.filepath = data;
next();
})
// end the input stream and allow the process to exit
pyshell.end(function (err) {
if (err){
throw err;
}
});
}
but it is working when i put next() at the end of code but then my req.filepath is undefined
const {PythonShell} = require('python-shell');
module.exports = (req, res, next)=>{
let myPythonScriptPath = 'encrypt.py';
const pyshell = new PythonShell(myPythonScriptPath);
let path = req.file.path;
pyshell.send(path);
pyshell.on("message", function(data){
console.log(data);
req.filepath = data;
})
// end the input stream and allow the process to exit
pyshell.end(function (err) {
if (err){
throw err;
}
});
next();
}
What i want is to store the data coming from python script in req.filepath which is to be sent to next middleware. Can anyone help me with this?
You're seeing this behavior due to the order of asynchronous tasks, which I've enumerated below in the comments. The execution doesn't necessarily happen in the same sequence that the code is written, so, you're either trying to modify a request/response after the PyShell command has already been sent (case #1 above), or Express has already moved on to the next middleware before req.filepath has been set (case #2 above).
const {PythonShell} = require('python-shell');
module.exports = (req, res, next) => {
let myPythonScriptPath = 'encrypt.py';
const pyshell = new PythonShell(myPythonScriptPath);
let path = req.file.path;
pyshell.send(path); // 1) Send the command
// 3) This anonymous function is invoked, but it's
// too late -- the command has already been sent
// and has continued on to the next middleware.
pyshell.on("message", function(data){
console.log(data);
// This will be undefined in the next middleware
// because it moved on before it was actually set.
req.filepath = data;
})
// 4) This anonymous function gets run last.
pyshell.end(function (err) {
if (err){
throw err;
}
});
next() // 2) Tell Express to continue on to the next middleware.
}
Do you have other middleware before or after this one that is trying to modify or send an HTTP response?
Using callback methodolgy this can be acheived by sending the result of the function in callback().(Here callback is next)
The code is given below:
const {PythonShell} = require('python-shell');
module.exports = function (req, res, next){
try{
let myPythonScriptPath = '/home/anmolmiddha/Projects/coreshare/server/api/python/encrypt.py';
const pyshell = new PythonShell(myPythonScriptPath);
let path = req.file.path;
pyshell.send(path);
pyshell.on("message", function(data){
});
pyshell.end(function (err, rslt) {
if(err){
res.status(500).json(err);
}
else{
req.filepath = JSON.stringify(path).split('"')[1];
next(rslt);
}
});
}
catch(error) {
return res.status(401).json({
message: "Invalid token Auth failed"
})
}
}

Cannot retrieve data from endpoint

I have installed Chatterbot for Django integration. I followed the easy tutorial with every step and made it so that the endpoint was: http://127.0.0.1:8000/chatterbot/ What I did next was try to communicate with that endpoint to see if I would get back any results. So I made an Ajax request as follows:
var query = {"text": "My input statement"};
$.ajax({
type: 'POST',
url: "http://127.0.0.1:8000/chatterbot/",
data: JSON.stringify(query),
contentType: 'application/json',
success: function (data) {
console.log(data);
}
});
However, what returns in console is: POST http://127.0.0.1:8000/chatterbot/ 403 (Forbidden) and what returns in the cmd prompt when I run my server is:
csrf: WARNING - Forbidden (CSRF token missing or incorrect.):
/chatterbot/ [29/Mar/2018 02:16:43] "POST /chatterbot/ HTTP/1.1" 403
2502
Why am I getting this error? How can I fix it so I receive the call back from the endpoint?
View for this page:
def IndexView(request):
latest_questions = Questions.objects.all().order_by("-date_published")[:5]
popular_questions = Questions.objects.all().order_by("-num_replies")[:5]
return render(request, 'core/index.html',
{'latest_questions': latest_questions, 'popular_questions': popular_questions
})
Try this code
// using jQuery
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
var query = {
"text": "My input statement",
"csrfmiddlewaretoken": csrftoken
};
$.ajax({
type: 'POST',
url: "http://127.0.0.1:8000/chatterbot/",
data: query,
contentType: 'application/json',
success: function (data) {
console.log(data);
}
});
one way is to send the csrfmiddlewaretoken like below
var query = {
"text": "My input statement",
'csrfmiddlewaretoken': "{{csrf_token }}"
};
other way is to use #csrf_exempt decorator
from django.views.decorators.csrf import csrf_exempt
#csrf_exempt
def IndexView(request):
# .... code.....
other is to add a script
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
Reference: https://docs.djangoproject.com/en/2.0/ref/csrf/
If you dont want to use CSRF tokens just add this above your code.
from django.views.decorators.csrf import csrf_exempt
#csrf_exempt
def IndexView(request):
# your code

Django DRF - How to do CSRF validation with token authentication

I am working on REST API using Django and Django Rest Framework.
In the front-end I have AngularJs app.
I have used Token authentication for APIs. This disables the CSRF checks.
I want keep CSRF validation with REST API. How to achieve this ?
How should I get CSRF Token value so that it can be set into the header of every POST request, using interceptor of my angular application.
I have this configuration in my app.js. Should do the trick!
app.config(function($httpProvider) {
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
});
I've got the same problem when i started to use Angular 1.x with Django and DRF, and then i found this code snippet in a book i think, and it works fine for me. Include this file in your base.html file or your main html file before any javascript import, and everything will work smoothly and you can start talking to your backend.
// Place at /static/js/csrf.js
// CSRF helper functions taken directly from Django docs
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/ ˆ (GET|HEAD|OPTIONS|TRACE) $ /.test(method));
}
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});

CSRF With Ajax Polling

I have some AJAX that polls the server every 5 seconds:
var date = $('article').first().find('time').text();
console.log(date);
setInterval(function() {
$.post('pollNewEntries', {'date':date}, newEntrySuccess)
}, 5000);
Unfortunately, I'm getting a 403 error every time the AJAX tries to poll the server, stating that I have made an invalid CSRF request. I've used AJAX with forms before and included the CSRF token within the forms, but I"m not sure how I would do it with a formless AJAX request like above.
The solution to this problem is described in the Django documentation: https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#ajax
Add this code to the top of your js:
$.ajaxSetup({
beforeSend: function(xhr, settings) {
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie != '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
}
}
});
You need to pass csrf token along with your post data:
var date = $('article').first().find('time').text();
console.log(date);
setInterval(function() {
$.post('pollNewEntries', {'date':date, 'csrfmiddlewaretoken': '{{csrf_token}}'}, newEntrySuccess)
}, 5000);
Simply add these lines in your script. Here is an example in coffeescript :
### CSRF methods ###
csrfSafeMethod = (method) ->
# these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method))
$.ajaxSetup(
crossDomain: false
beforeSend: (xhr, settings) ->
if !csrfSafeMethod(settings.type)
xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'))
)
Read the documentation : CSRF
In other hand, as user1427661 suggests to you, it will be better to use HTTP GET method instead of POST, because you only need to read data and don't write anything. See the W3 docs.

Categories

Resources