Flask not interacting with Ajax - python

This script
<script type="text/javascript">
$(function() {
$('.send').live('click', 'button', function()
{
var user1 = $(this).val();
var user2=$(this).prev().val();
var text=$(this).prev().prev().val();
var my_data = {
user1: user1, text:text, user2:user2,
};
console.log(my_data)
$.ajax({
url: "/updatechat",
data: my_data,
type: 'POST',
success: function(response) {
console.log(response)
},
error: function(error) {
console.log(error);
}
});
});
});
is raising an error with the correspondent route /updatechat
#app.route('/updatechat', methods=['GET','POST'])
def updatechat():
user1 = request.form['user1']
user2 = request.form['user2']
text = request.form['text']
return [user1,user2,text] #not the actual code
but will NOT raise the same error if, in the previous piece of code, i replace with this
user1='bbb'
user2='whatever'
text='idk'
this "var = request.form['var']" form works on several different routes on my code

Solved
The proper form was user1 = request.values.get("user1")
source: https://stackoverflow.com/a/20341272

Related

Python requests login with jsencrypted post

ive been trying to login with the following code in a chinese monitoring system that uses js forms.
i assume i cannot log in because the payload is encrypted with a public key and posted to a randomly generated URL.
import sys, re, requests
class GMU:
def __init__(self):
payload = {'inputAccount': 'admin','inputPassword': 'admin'}
s = requests.Session()
p = s.post('http://10.40.100.146/',data=payload)
self.p = p
r = s.get('http://10.40.100.146/ActiveSignal/ActiveSignalPartial?equipmentId=300001003')
data = str(r.content)
self.data = data
def ask():
return GMU()
n = ask()
print(n.p)
print(n.data)
Here is a post header
Payload
Initiator
looking in the initatior section "send" i found loginname.js with the following code:
var publicKey = "-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6MqYui/VMzy0qQE2c6S24fNbph7Hr/Nh29aJJ0kWjINV3zPgJXZrmJp43PaQBxHkq3cESuSf9zUCBS0wZtvFL8LTU1Iehnh/rPVKfGHQaHoD928n7CXuGwnEsyl63p6wwgIjiENVTMaReCJz79N2fhXFK99cA1/B7JXRtCPr/pwIDAQAB-----END PUBLIC KEY-----";
var clientMenuTemplateType = 4;
function logout() {
BootstrapDialog.show({
title: lang["Exit the confirmation"],
message: lang["Quit or not?"],
cssClass: 'user-dialog',
buttons: [{
label: lang["Confirm"],
cssClass: 'btn blue btn-outline dropdown-toggle',
action: function () {
//执行操作
location.href = '.././Account/Logout';
}
}, {
label: lang["Cancel"],
action: function (dialog) {
dialog.close();
}
}]
});
}
$("#loginBtn").click(function () {
Login();
});
$('#inputPassword').bind('keyup', function (event) {
if (event.keyCode == "13") {
//回车执行
Login();
}
});
$('#inputAccount').bind('keyup', function (event) {
if (event.keyCode == "13") {
//回车执行
Login();
}
});
$('#loginBtn').bind('keyup', function (event) {
if (event.keyCode == "13") {
//回车执行
Login();
}
});
var flag = 0;
$("#pswdVisual").click(function () {
var input = document.getElementById('inputPassword');
if (flag == 0) {
input.type = 'text';
$("#pswdVisual").addClass("glyphicon-eye-open");
$("#pswdVisual").removeClass("glyphicon-eye-close");
flag = 1;
} else {
input.type = 'password';
$("#pswdVisual").addClass("glyphicon-eye-close");
$("#pswdVisual").removeClass("glyphicon-eye-open");
flag = 0;
}
});
function Login() {
var options = {
positionClass: 'toast-bottom-right'
}
var account = $('#inputAccount').val();
var password = $('#inputPassword').val();
if (!account || account == null || account === "") {
toastr.error(lang["Username cannot be empty!"], lang["login failure"], options);
} else if (!password || password == null || password === "") {
toastr.error(lang["Password cannot be empty!"], lang["login failure"], options);
} else {
var data = account + "&" + password;
//RSA Encrypt
var jsEncrypt = new JSEncrypt();
jsEncrypt.setPublicKey(publicKey);
var key = jsEncrypt.encrypt(data);
$.ajax({
type: "post",
url: currentUrl + "Account/LoginAction/?t=" + Math.random(),
data: {
encryptContext: key
},
dataType: "json",
success: function (response) {
if (response != null) {
if (response.url !== "") {
cookieObject.setCookie("userName", account);
if (response.url.indexOf("Default/Default?ZT=") !== -1) {
location.href = currentUrl + "Default/Default#ZT=" + response.url.replace("Default/Default?ZT=", "");
} else {
location.href = currentUrl + "Default/Default#Page=" + response.url;
}
}
else if (response.error !== "")
console.log(response.error);
else if (response.show !== "") {
if (response.show == lang["The user name does not exist"]) {
toastr.error("", lang["login failure"], options);
} else {
toastr.error(response.show, lang["login failure"], options);
}
}
}
},
error: function () {
}
});
}
};
i dont know if should be passing the rsa encrypted payload or there is some way to just provide the user and password and let the js thing generate itself.

How to upload a file using expo react native?

The issue.
My code below works (uploads the file) when I run it on my phone using expo r -c
Does NOT work (no files in request object) when i run npm run web or expo r -c followed by w
import { StatusBar } from "expo-status-bar";
import { StyleSheet, Text, View, Button } from "react-native";
import * as DocumentPicker from "expo-document-picker";
export default function App() {
const _pickDocument = async () => {
let result = await DocumentPicker.getDocumentAsync({
type: "*/*",
copyToCacheDirectory: true,
});
alert(result.uri);
console.log(result);
const imageUri = result.uri.replace("file:/data", "file:///data");
const data = new FormData();
data.append("file", {
name: result.name,
type: result.mimeType,
uri: imageUri,
});
const options = {
method: "POST",
body: data,
headers: {
Accept: "application/json",
"Content-Type": "multipart/form-data",
},
};
const base_domain =
"http://192.168.1.83:5000" + "/api/v1/manager/file-upload";
fetch(base_domain, options).catch((error) => console.log(error));
};
return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
<StatusBar style="auto" />
<Button title="Select Document" onPress={_pickDocument} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
});
Backend
#manager.route("/file-upload", methods=["POST"])
#csrf.exempt
def upload_file():
# check if the post request has the file part
print("Request Files", request.files)
return jsonify({"status": "ok"})
For the web case request.files gives me an empty dict.

xlsx file not being exported django rest framework

I am calling ajax request from frontend to export data in excel sheet.
js
function exportData(){
create_spinner("Please wait while we export data.");
var agent = $("#agent").val()
var dateRange = $("#dateRangeValue").val()
var queue = $("#queue").val()
var direction = $("#direction").val()
var department = $("#department").val()
var serviceLevel = $("#sl").val()
$.ajax({
type: 'POST',
url: "/call-record-api/export-data/",
data: {
"agent": agent,
"dateRange": dateRange,
"queue": queue,
"direction": direction,
"department": department,
"serviceLevel": serviceLevel,
},
success: function(resultData) {
console.log("success");
hide_spinner();
},
error: function (err) {
console.log("AJAX error in request: " + JSON.stringify(err, null, 2));
create_spinner("Couldn't export data. Please try again");
setTimeout(function(){ hide_spinner()}, 1000);
}
});
}
I have gone through documentation and implemented the same.
urls.py
url(r'^call-record-api/export-data/$', ExportCallRecordView.as_view({"post":"list"})),
views.py
class ExportCallRecordView(XLSXFileMixin, ReadOnlyModelViewSet):
def get_queryset(self):
calls = export_customized_calls(self.request)
print(calls.count())
return calls
serializer_class = CallRecordSerializer
renderer_classes = [XLSXRenderer]
filename = 'call_record_export.xlsx'
But i cannot see the file getting downloaded. However i can see success in browser console and 235 as call count in server console.
You can't download files directly with ajax. You have to use tricks like this (taken from a github repo):
// jQuery ajax
$.ajax({
type: "POST",
url: url,
data: params,
success: function(response, status, xhr) {
// check for a filename
var filename = "";
var disposition = xhr.getResponseHeader('Content-Disposition');
if (disposition && disposition.indexOf('attachment') !== -1) {
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
}
var type = xhr.getResponseHeader('Content-Type');
var blob = new Blob([response], { type: type });
if (typeof window.navigator.msSaveBlob !== 'undefined') {
// IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."
window.navigator.msSaveBlob(blob, filename);
} else {
var URL = window.URL || window.webkitURL;
var downloadUrl = URL.createObjectURL(blob);
if (filename) {
// use HTML5 a[download] attribute to specify filename
var a = document.createElement("a");
// safari doesn't support this yet
if (typeof a.download === 'undefined') {
window.location = downloadUrl;
} else {
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
}
} else {
window.location = downloadUrl;
}
setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
}
}
});
Or if you don't mind converting your POST request in to GET request:
window.location = `/<download_url>/?param1=${encodeURIComponent(param1)}`

Send file path from flask to Ajax

I'm trying to send a file path to my Ajax script which reads file contents and displays it on the page
#app.route('/main', methods=['GET'])
def main():
filename = '/static/js/'+current_user.username+'log.txt'
return render_template('main.html',name=current_user.username,data=filename)
js script
var checkInterval = 1; //seconds
var fileServer = '{{ data }}';
var lastData;
function checkFile() {
$.get(fileServer, function (data) {
if (lastData !== data) {
$( "#target" ).val( data );
$( "#target" ).animate({
scrollTop: $( "#target" )[0].scrollHeight - $( "#target" ).height()
}, 'slow');
lastData = data;
}
});
}
$(document).ready(function () {
setInterval(checkFile, 1000 * checkInterval);
});
I tried different ways to do this, changed fileServer to 'data.filename'/{{ data| json }} etc but got no luck.
How can I do this?
If you pass the entire url generated with url_for as a parameter it should work.
#app.route('/main', methods=['GET'])
def main():
filename = url_for('static', filename=f'js/{current_user.username}log.txt')
return render_template('main.html', name=current_user.username, data=filename)
As a supplement, I also specify that the request should not be stored in the cache.
const checkInterval = 1;
const fileServer = "{{ data }}";
let lastData;
function checkFile() {
$.get({ url: fileServer, cache: false }, function(data) {
if (lastData !== data) {
$("#target").val(data);
$("#target").animate({
scrollTop: $("#target")[0].scrollHeight - $("#target").height()
}, "slow");
lastData = data;
}
});
}
$(document).ready(function() {
setInterval(checkFile, 1000 * checkInterval);
});
I used jquery version 3 for testing.

400 bad Request using axios, flask and react

I am unable to make post request via react js to python-flask server.
I am using axios. This request works on postman, but I can't seem to figure out why I can make post request from my react app.
Please see flask code:
#app.route('/match_home_types', methods=['GET', 'POST'])
def match_home_types():
area = request.form['area']
response = jsonify({
'home_types': util.match_area_with_types(area)
})
response.headers.add('Access-Control-Allow-Origin', '*')
return response
My react-redux action code:
export const matchHouseTypes = (area) => (dispatch) => {
axios
.post("http://127.0.0.1:5000/match_home_types", area)
.then((res) => {
dispatch({
type: MATCH_TYPES,
payload: res.data.home_types,
});
})
.catch((error) => {
console.log(error.response);
});
};
my react class component:
get_house_types = () => {
const { selectedOption } = this.state;
if (selectedOption == "Find a location") {
alert("Please select a valid location");
}
var area = {
area: selectedOption.replace(/(^\w|\s\w)/g, (m) => m.toUpperCase()),
};
console.log("area:", area);
this.props.matchHouseTypes(area);
};
See below error response from axios:
data: "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">↵<title>400 Bad Request</title>↵<h1>Bad Request</h1>↵<p>The browser (or proxy) sent a request that this server could not understand.</p>↵"
status: 400
statusText: "Bad Request"
Please assist
The issue was that I was not sending the API parameters the right way. Since I am sending via form data I changed my code from:
var area = {
area: selectedOption.replace(/(^\w|\s\w)/g, (m) => m.toUpperCase()),
};
to:
const formData = new FormData();
formData.append(
"area",
selectedOption.replace(/(^\w|\s\w)/g, (m) => m.toUpperCase())
);
complete function:
get_house_types = (e) => {
e.preventDefault();
const { selectedOption } = this.state;
if (selectedOption == "Find a location") {
alert("Please select a valid location");
} else {
const formData = new FormData();
formData.append(
"area",
selectedOption.replace(/(^\w|\s\w)/g, (m) => m.toUpperCase())
);
this.props.matchHouseTypes(formData);
}
};

Categories