I'm trying to post some data to a Python backend that i made with Flask. I'm using SuperAgent in a React component. For some reason i keep getting HTTP error 400.
I've read many posts about similar problems using JQuery and flask. The solution there is to set the contentType the same way i have and also JSON.stringify the data. I've tried stringify but it doesn't change anything. Still getting an HTTP 400.
Any ideas?
JS code:
request.post(link)
.set('Content-Type', 'application/json; charset=utf-8')
.send({tag: 'tag1', comment: 'Cool'})
.end(function(err, res){
console.log(res);
});
Python function/endpoint:
#app.route('/api/leavecomments', methods=['POST'])
def comment_to_photos():
comment = request.form['comment']
print(comment)
tag = request.form['tag']
...
So the issue for anybody else that has this problem, they need to use method named get_json which will have the values being passed to it in JSON format. In the case of the code above it was looking for those values as a query string post parameters, which is typically sent via form posts. In the case of an AJAX JSON post, the data exists inside the request.body.
For more information check out...
http://flask.pocoo.org/docs/0.10/api/#flask.Request.get_json
Related
I am learning Django 1.6.
I want to post some JSON using HTTP POST request and I am using Django for this task for learning.
I tried to use request.POST['data'], request.raw_post_data, request.body but none are working for me.
my views.py is
import json
from django.http import StreamingHttpResponse
def main_page(request):
if request.method=='POST':
received_json_data=json.loads(request.POST['data'])
#received_json_data=json.loads(request.body)
return StreamingHttpResponse('it was post request: '+str(received_json_data))
return StreamingHttpResponse('it was GET request')
I am posting JSON data using requests module.
import requests
import json
url = "http://localhost:8000"
data = {'data':[{'key1':'val1'}, {'key2':'val2'}]}
headers = {'content-type': 'application/json'}
r=requests.post(url, data=json.dumps(data), headers=headers)
r.text
r.text should print that message and posted data but I am not able to solve this simple problem. please tell me how to collect posted data in Django 1.6?
You're confusing form-encoded and JSON data here. request.POST['foo'] is for form-encoded data. You are posting raw JSON, so you should use request.body.
received_json_data=json.loads(request.body)
For python3 you have to decode body first:
received_json_data = json.loads(request.body.decode("utf-8"))
Create a form with data as field of type CharField or TextField and validate the passed data. Similar SO Question
So I am not sure which side of the code is wrong, the javascript or the python.
Basically I have reactjs forms, which are then to be submitted to the server and dealt with through cherrypy functions. The requests themselves are allegedly going through, but they aren't receiving any of the data I am sending.
Here is an example of one of the requests and the python function:
handleSubmit(e){
var example = this.props.value;
const request = axios.post(someUrl+'/pythonFunction', {example})
.then(function(response){
console.log('successfully posted', example);
})
}
Now here is the Python code of the function this is being done at:
#cherrypy.tools.allow(methods='POST')
#cherrypy.tools.json_out()
def pythonFunction(self, **kwargs):
# does stuff with data received
So, the problem is nothing is being received on the python end of things. The parameters such as kwargs will always be empty no matter how much I double and triple check to make sure things are being sent off appropriately.
Any ideas as to where the problem actually is and how to fix it?
Edit: not sure if relevant, but the data I am trying to post does appear on the Request Payload
Here's how to read JSON formatted payload (submitted via any HTTP method, which includes body):
#cherrypy.tools.allow(methods='POST')
#cherrypy.tools.json_out()
#cherrypy.tools.json_in()
def pythonFunction(self, *args **kwargs):
data = cherrypy.request.json
return data
I tried to use Angular $http.post(url, data) method. But I am facing some problems to post correct data to server (WebAPI). I have tried follwing options but none is working.
var data1 = new Object();
data1.UserName = "UserA1";
data1.Password = "password123";
data1.ConfirmPassword = "password123";
var data2 = angular.toJson(data1);
var data3 = JSON.stringify(data1);
var data4 = { UserName: "UserA2", Password: "password123", ConfirmPassword: "password123" };
var data5 = "UserName=UserA3&Password=password123&ConfirmPassword=password123";
$http.post(url, data1)
$http.post(url, data2)
$http.post(url, data3)
$http.post(url, data4)
$http.post(url, data5)
None is working. What kind of data is correct for this method. I tried JQuery.post() with above data and it works. Its super strange for me why this simple angularjs method so hard to use or I am missing something.
Update:
Basically I am working on following example. I want to register user from client side (/api/Account/Register).
http://www.asp.net/web-api/overview/security/individual-accounts-in-web-api
This is because your server-side expects a request with its content x-www-form-urlencoded.
jQuery's $.post() sends the request with a Content-type of application/x-www-form-urlencoded whereas Angular's $http.post() sends the request with a Content-type of application/json (and also encodes the data as JSON (instad of form-data) if a JS Object is passed).
There are methods you can send x-www-form-urlencoded requests using $http (and there are several related answers on SO), but it involves less straight-forward code.
I suggest you change your server side to consume JSON requests.
Depending on what you have on server side, you should transform your request (that's the case for PHP, for example, or you can read from the input stream: php://input).
See this gist: https://gist.github.com/JensRantil/5713606.
If this is not solving your problem, please inspect the requests angular is creating (using the Developer Tools -> Network tab in Chrome for example), and tell us what you see.
Using a normal html form, I can add a new task by sending POST request to /api/tasks/insert/
POST data includes $name and $description of the task.
However, when I use Angular to push the data to REST API in php, only a POST request is sent and an empty row is created in the database.
This means that the POST variables are not being passed i.e. name and description.
What am I doing wrong?
I have been stuck at this for the last few hours now. I have checked countless tutorials and am pretty sure of the syntax. My backend REST api in PHP works fine.
var res=$resource('http://localhost/api/tasks/insert/',{},
{
createTask:{method:'POST'}
});
postData={name:"Hello",description:"DescBaby"}
res.createTask({},postData);
//res.createTask(postData); tried this also, but doesn't work
Another variation that I tried based on an comment was this:
res.createTask({name:"TestName", description:"descBaby"}).$promise.then(function(value)
{
console.log("Success"); //I get success in console.
},function(errResponse)
{
console.log("Error");
});
Angular Does not give me any errors. Just sends a blank POST request to the url.
EDIT:
I checked in the network pane in Chrome whether the data was sent or not and as it turns out it is being sent.
However, in the response it's showing this :
Undefined index: name in XYZ.php line ABC.
The line pointed above is the following line in my PHP:
$obj->InsertTask($_POST['name'],$_POST['description']);
Thanks to a friend of mine, I finally got the code running. The problem wasn't with my Angualar Code but with php code.
As it turns out I cannot read POST data as $_POST[].
file_get_contents should be used in such cases as data is sent through a JSON payload and not through request parameters!
Here's how I got it running : Angularjs $http.post, passing array to PHP
Did you look at the network tab of debugger? You can check if valid data was sent to server. If it was ok this is not JS or Angular question. On the first look it seems that you have valid code for angular. Just in case check if you have set proper ajax headers.
"X-Requested-With": "XMLHttpRequest"
Does other AJAX calls work for you?
Try this (and create a factory to follow the best practices):
Service
services.factory("Tasks", function($resource) {
return $resource('http://localhost/api/tasks/insert/', {}, {
createTask: {method:'POST', params: {name:"Hello",description:"DescBaby"}}
})
});
Controller
Tasks.$createTask();
I'm switching from jquery $.ajax, which was working fine, to using AngularJS $http.put to access a restful API.
I can make an API call, but the PUT data isn't getting sent - so my API sees a PUT request with an empty data object, which should contain a JSON string -> data.values = 'a json structure'
$http.put(
$rootScope.api_url,
{
values: jsonifiedValues
},
{
headers: {
apihash: sha256hash
}
}).success(function(data,status,headers,config){
// handle success
}).error(function(data,status,headers,config) {
// handle failure
});
I've not used AngularJS's $http before, but when I dump out the data in my PHP api it's just empty. this is how I'm pulling it from the request in the PHP:
parse_str(file_get_contents('php://input'), $put_vars);
$arr_req_data = $put_vars['values'];
In my API if the apihash sent from the request doesn't match the sha256 hash built on the PUT values, it fails.
This is working in JQuery, just failing now I've switched to $http. I'm not sure why the PUT data seems to be empty.
The return value from file_get_contents('php://input') will be a JSON string (provided everything got sent), so parse_str is not the right function to handle that data.
Instead use json_decode.
Also there is no need to send jsonified values, it will just make things more complicated as you'll have to use json_decode twice.