How do I send a json POST request using Javascript and read it on a flask server?
Last approach (reference):
const uploadjson = storeDictionary
const url = "/uploadset/"+setName
fetch(url, {method: 'POST', // or 'PUT'
headers: {
'Content-Type': 'application/json',
},
body: uploadjson})
.then((response) => response.json())
.then((data) => {
console.log('Success:', uploadjson);
})
.catch((error) => {
console.error('Error:', error);
console.log("Data:", uploadjson)
});
It results in the following error message:
Here's a part of the python code (flask) I wrote with help from the documentation:
#app.route("/uploadset/<name>", methods=['GET','POST'])
def uploads(name):
if flask.request.method == "POST":
print("Upload!")
if 'id' in flask.session:
if flask.session['id'] in client:
sessid = flask.session['id']
if name != "":
print("flask.request.files", flask.request.files)
file = flask.request.files['file']
try:
if processUploadedSet():
error = False
success = True
This results into a "server didn't understand your request".
I found out that the flask server is the problem:
Here's the server log:
If I return an empty string on the server the request works 'fine'.
How do I read json data using flask which was sent using the javascript?
You can read a json response in flask using flask.request.get_json
Simply replace file = flask.request.files['file']
with file = flask.request.get_json(cache=False)
Sending a json POST request is not the same as sending a file!
Related
I m newbie who is learning to play with API. I m getting POST req error while using axios.
In docs of API which I want to interact, they give curl example.
curl -X POST https://ssuploader.streamsb.com/upload/01
-d "api_key=948324jkl3h45h"
-d "#path/filename.mp4"
-H "Content-Type: application/x-www-form-urlencoded"
I am trying to make that POST request using axios. I wrote simple script like this.
const axiosConfig = {
headers : {
"Content-Type": "application/x-www-form-urlencoded"
}
}
const file = __dirname + "/video/Video.mp4";
const fileData = fs.readFileSync(file);
const data = `api_key=${API_KEY}&${fileData}`;
axios.post('https://ssuploader.streamsb.com/upload/01', data, axiosConfig).then((result) => {
console.log(result.data);
}).catch((err) => {
console.log("Getting Error : ", err);
});
I am getting this error.
Getting Error : AxiosError: getaddrinfo ENOTFOUND ssuploader.streamsb.com
I m really new to interacting with API, so that I thought some of my structure was wrong while converting curl to axios. I really don't know what to do. I mean I can't figure out my false. Can anyone help me? Thank you so much.
Some Changes
I figure out some of my false with the help of answers. I forget to GET the server first. So that I updated my code to this.
const file = __dirname + "/video/Video.mp4";
const fileData = fs.createReadStream(file);
const formData = new FormData();
formData.append('file', fileData);
formData.append('api_key', API_KEY);
console.log(formData)
axios.get(`https://api.streamsb.com/api/upload/server?key=${API_KEY}`).then(result => {
const url = result.data.result;
axios.post(url, formData, axiosConfig)
.then((result) => {
console.log(result.data);
}).catch((err) => {
console.log("Getting Error : ", err);
});
})
But I am getting new Error.
AxiosError: Request failed with status code 400
As I understand from the documentation this is 2 step process. At first you need to get the upload URL (server as they call it) and then use it to upload your file.
So use something like this:
axios.get(`https://api.streamsb.com/api/upload/server?key=${API_KEY}`).then((result) => {
const url = result.data.result;
// your post request to this url here
}).catch((err) => {
console.log("Getting Error : ", err);
});
You are sending fileData as a string in the data Object
Use 'Content-Type': 'multipart/form-data'instead of using "Content-Type": "application/x-www-form-urlencoded"
Code will be like this
import FormData from 'form-data';
const axiosConfig = {
headers: {
'Content-Type': 'multipart/form-data'
}
}
const file = __dirname + "/video/Video.mp4";
const fileData = fs.createReadStream(file);
const formData = new FormData();
formData.append('file', fileData);
formData.append('api_key', API_KEY);
axios.post('https://ssuploader.streamsb.com/upload/01', formData, axiosConfig)
.then((result) => {
console.log(result.data);
}).catch((err) => {
console.log("Getting Error : ", err);
});
If you have any query, you can ask
It's them, not you.
There is no DNS record for ssuploader.streamsb.com (you can enter it into https://mxtoolbox.com/DNSLookup.aspx to check), which means that when you try to connect to it, it leads nowhere.
Unless you do some digging and find a domain from them that has a DNS record, there isn't anything you can do.
Using fetch I'm getting a bad request as well as unexpected token < in JSON both point to search.js which is where I'm making the fetch request I have tried sending via an API client and it is working I'm trying to send the fetch request via input onkeyup.
Also noticed my error is uncaught
Fetch req:
const searchResults = function(e){
fetch('/elpers/search' ,
{
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(e.value)
}).then(res => {
res.json()
}).then(data => {
console.log(data)
}).catch(err => {
console.error(err)
})
}
POST route
const postSearch = (req, res) => {
console.log(req.body)
res.send({'result': 'value'});
}
edit: this worked for me JSON.stringify({result: e.value})
Error:
search.js:2 POST http://localhost:3000/elpers/search 400 (Bad Request) VM118:1 Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0
use this ans let me know:
const postSearch = (req, res) => {
console.log(req.body) // post if data is received here...
res.json({
message: "data received!",
data: search, // search should be the data that user fetched
})
};
On the client side, just console.log the data received and see if it is JSON or not :)))
Happy coding!
You need to use res.json() instead of res.send() and JSON.stringify(e.value) to JSON.stringify({result: e.value})
I'm trying to make a post request from a webpage to a Wildfly Camunda server to start a task. It works using postman with localhost:8080/engine-rest/message, but when I use the webpage all I get is Type error: failed to fetch. I have tried just using localhost:8080/engine-rest/message but gets:
Fetch API cannot load localhost:8080/engine-rest/message. URL scheme must be "HTTP" or "HTTPS" for CORS request.
/* And */
Error: TypeError: Failed to fetch at HTMLFormElement.<anonymous>
And if I set mode : no-cors I get Fetch API cannot load localhost:8080/engine-rest/message. URL scheme "localhost" is not supported. and Error: TypeError: Failed to fetch at HTMLFormElement.<anonymous>
const form = document.getElementById('myForm');
form.addEventListener('submit', function() {
// alert("Request sent");
const urlHttp = 'http://localhost:8080/engine-rest/message';
const url = "localhost:8080/engine-rest/message";
const data = {
messageName: 'start',
businessKey: '7'
};
// send POST request
fetch(urlHttp, {
method: 'POST',
// mode : 'no-cors',
headers: {
'Content-Type': 'application/json; charset=UTF-8;',
// 'Accept' : 'application/json'
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});
});
I am trying to make a javascript request to a python backend rest, and getting errors I cannot resolve. I am trying to test if a listname is in a request.json object that I am passing through the axios data, but python either can't see it or throws an error.
Here is my python code:
#app.route('/', methods=['GET', 'DELETE', 'POST'])
def profits():
if request.method=='GET':
if 'listname' in request.json():
print 'inside listname == True!!!'
conn = psycopg2.connect(database = "profitnloss3", user = "patientplatypus", password = "*************")
cur = conn.cursor()
sql = 'SELECT * FROM ledger WHERE listname = %s'
params = (request.json['listname'])
cur.execute(sql, params)
conn.commit()
data = cur.fetchall()
conn.close()
return jsonify(data)
else:
print 'inside listname == False!!!'
conn = psycopg2.connect(database = "profitnloss3", user = "patientplatypus", password = "*******************")
cur = conn.cursor()
sql = 'SELECT * FROM ledger'
cur.execute(sql)
conn.commit()
data = cur.fetchall()
conn.close()
return jsonify(data)
The relevant line that is giving me trouble is if 'listname' in request.json():
Here is the axios call that I am making in the front end:
axios({
method: 'get',
url: 'http://localhost:5000/',
headers: {
'Content-type': 'application/json'
},
data:{
'listname': this.ledgername
}
})
.then((response)=>{
console.log('this is the response from the python server on a get request of listname ', response);
})
.catch(error=>{
console.log('here is the error on a get request from the python server of listname ', error);
})
The error that I am getting is:
TypeError: 'NoneType' object is not callable
If I instead use if 'listname' in request.json:
TypeError: argument of type 'NoneType' is not iterable
I have also tried using the form variable (ie request.form) but the values are then completely ignored from the axios post even though an error is not thrown (I guess it doesn't see it as form data).
I do not know where to go from here, any help would be appreciated.
EDIT:
My import header at the top of my python file is
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS, cross_origin
import sqlite3
import psycopg2
import os
from os.path import join, dirname
from dotenv import load_dotenv
from models.shared import db
from models.profits import Profit
I guess you are not sending the data at all because according to the axios documentation the data option is „Only applicable for request methods 'PUT', 'POST', and 'PATCH'“.
So you have to use a POST request (and change the server code accordingly):
axios({
method: 'post',
url: 'http://localhost:5000/',
headers: {
'Content-type': 'application/json'
},
data: {
'listname': this.ledgername
}
})
.then((response) => {
console.log('this is the response from the python server on a post request of listname ', response);
})
.catch((error) => {
console.log('here is the error on a post request from the python server of listname ', error);
});
or sending the listname as GET parameter instead of as JSON in the request body.
I'm invoking an authentication service via javascript fetch to get an access token. The service is a simple RESTful call. I can see the call is successful using fiddler (with a 200 response and json data). However the fetch response never seems to get invoked. Below is a snippet:
const AUTHBODY = `grant_type=password&username=${username}&password=${password}&scope=roles offline_access profile`
const AUTHHEADER = new Headers({'Content-Type': 'application/x-www-form-urlencoded'})
const CONFIG = {
method: 'POST',
headers: AUTHHEADER,
body: AUTHBODY
}
fetch('http://localhost:23461/connect/token', CONFIG).then(function(response) {
console.log('response = ' + response)
return response.json()
}).then(function(json) {
console.log('json data = ' + json)
return json
}).catch(function(error) {
console.log('error = ' + error)
})
When executing the fetch above none of the console.logs gets executed... seems to just hang. But fiddler tells otherwise. Any ideas?
You probably met with the CORS origin policy problem. To tackle this you need some rights to access the server side of your API. In particular, you need to add a line in the header of php or another server endpoint:
<?php
header('Access-Control-Allow-Origin: *');
//or
header('Access-Control-Allow-Origin: http://example.com');
// Reading JSON POST using PHP
$json = file_get_contents('php://input');
$jsonObj = json_decode($json);
// Use $jsonObj
print_r($jsonObj->message);
...
// End php
?>
Also, make sure NOT to have in the header of your server endpoint:
header("Access-Control-Allow-Credentials" : true);
Model of working fetch code with POST request is:
const data = {
message: 'We send a message to the backend with fetch()'
};
const endpoint = 'http://example.com/php/phpGetPost.php';
fetch(endpoint, {
method: 'POST',
body: JSON.stringify(data)
})
.then((resp) => resp.json())
.then(function(response) {
console.info('fetch()', response);
return response;
});