I get a net::ERR_EMPTY_RESPONSE error:
only on deployed version, not localhost
other GET-requests work
It downloads all my files from the ftp-server but it returns an error.:(
Flask Backend:
app = Flask(__name__)
cors = CORS(app)
#app.route('/downloadftp', methods=['POST'])
#cross_origin()
def download_all_ftp_data():
# connect to sever...
# download files...
for f in ftp.nlst():
fhandle = open(f, 'wb')
ftp.retrbinary('RETR ' + f, fhandle.write)
ftp.quit()
return 'OK 200'
React Frontend:
useEffect(() => {
axios
.post(`${process.env.REACT_APP_HOST}/downloadftp`, { content: "post" })
.then(res => {
console.log(res)
setError(false)
})
.catch(function (err) {
console.log(err)
setError(true)
})
}, [])
The error is due to the amount of data to download as it is described here: getting this net::ERR_EMPTY_RESPONSE error in browser
The solution for my problems was creating a daemon thread. The response is sent directly after starting the background thread.
from multiprocessing import Process
#app.route('/downloadftp')
#cross_origin()
def get_all_ftp_data():
"""creates a daemon thread for downloading all files while the response it sent directly after starting the background thread."""
daemon_process = Process(
target=download_data_multiprocessing,
daemon=True
)
daemon_process.start()
return Response(status=200)
def download_data_multiprocessing():
"""triggers download current data from ftp server"""
# connect to sever
# download
for f in ftp.nlst():
if (f != '.' and f != '..' and "meteo" not in f):
fhandle = open(f, 'wb')
ftp.retrbinary('RETR ' + f, fhandle.write)
ftp.quit()
Related
I'm using React + Django. Simple backend with one button on frontend handling POST requests:
function handleSubmit(e){
e.preventDefault();
axios.post(API_URL, {
forklift, battery
}).then((response) => {
console.log(response)
}).catch((error) => {
console.log(error.response)
});
}
The problem is when I try to submit the form while including .catch it always throws an 404 error on first request and then my development server on django crashes on second request (stops). When I delete catching error it works perfectly.
function handleSubmit(e){
e.preventDefault();
axios.post(API_URL, {
forklift, battery
}).then((response) => {
console.log(response)
});
}
My Django API_VIEW
#api_view(['POST'])
def start_charging(request):
if request.method == 'POST':
print('test')
forklift_ean = request.data['forklift']
battery_ean = request.data['battery']
try:
forklift = Forklift.objects.get(for_ean=forklift_ean)
battery = Battery.objects.get(bat_ean=battery_ean)
except Forklift.DoesNotExist or Battery.DoesNotExist:
return Response({'error_message': "No object error"},
status=status.HTTP_404_NOT_FOUND)
return Response({"message": "OK"})
Main url.py file
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('my_app.urls'))
]
App url.py file
urlpatterns = [
path('charging/', views.start_charging, name='start_charging'),
]
Error on first request:
xhr.js:220 POST http://127.0.0.1:8000/api/charging/ 404 (Not Found)
Error on seconds request (server crashes):
xhr.js:220 POST http://127.0.0.1:8000/api/charging/ net::ERR_CONNECTION_REFUSED
I am using corsheaders in my django project and the frontend is allowed to send requests:
CORS_ALLOWED_ORIGINS = [
'http://localhost:3000',
]
Any idea why might be the reason for .catch to act that way?
I'm trying to upload files from my web app to my flask server that serves as API for the app.
As mentioned in the title I'm using Nginx as my webserver and running the flask app using WSGI.
This is the code in the webapp (React):
const formData = new FormData()
files.forEach((file) => {
formData.append("files", file)
})
console.log('files', files)
console.log('formData', formData)
axios.post('https://api.web.app/uploadfile', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(response => {
console.log('response.data.imgUrls', response.data.imgUrls)
if (DLOrSOW === 'sow') {
setSOWImgUrls(response.data.imgUrls)
} else {
setDLImgUrls(response.data.imgUrls)
}
})
}
This is the code on Flask:
#app.route('/uploadfile', methods=['POST'])
# #token_required
def upload_file():
print("Req is POST")
# check if the post request has the file part
if 'files' not in request.files:
print("No file found")
flash('No file')
return redirect(request.url)
files = request.files.getlist('files')
print(" files ", files)
filePaths = []
for file in files:
if file.filename == '':
flash('No selected file')
return redirect(request.url)
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
print("url_for('download_file', name=filename)", url_for('download_file', name=filename))
filePaths.append(url_for('download_file', name=filename))
return jsonify({'imgUrls':filePaths })
Client(browser) respond in Console:
Request header field Authorization is not allowed by Access-Control-Allow-Headers.
[Error] XMLHttpRequest cannot load https://api.web.app/uploadfile due to access control checks.
On the other side in Flask logs I can see this request:
Oct 20 18:31:49 API uwsgi[1709272]: [pid: 1709272|app: 0|req: 36/81] 111.11.11.1 () {50 vars in 805 bytes} [Wed Oct 20 18:31:49 2021] OPTIONS /uploadfile => generated 6 bytes in 6 msecs (HTTP/1.1 200) 3 headers in 110 bytes (1 switches on core 0)
Just want to add that everything else works as it should. I'm able to do post, get, put etc requests to every other path in the Flask.
I think that the part that causes this is the use of "new FormData()"
In this case, for my situation, the problem was fixed by adding 'GET' parameter in the Flask path:
#app.route('/uploadfile', methods=['GET, 'POST'])
Apparently the order of the methods is important too
I could really use some help. I can't figure out what I'm doing wrong. I keep getting
Edit : Frontend React application runs on localhost:3000, backend is running on localhost:5000
Access to XMLHttpRequest at 'http://localhost:5000/api/auth/login' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
def create_app(test_config=None):
logger = logging.getLogger(__name__)
logger.info("Flask App Starting")
# create and configure the app
app = Flask(__name__, instance_relative_config=True)
CORS(app)
cors = CORS(app, resources={r"/api/*": {"origins": "*"}})
logging.getLogger('flask_cors').level = logging.DEBUG
app.config.from_mapping(
SECRET_KEY="dev",
JWT_SECRET_KEY="super secret key",
JWT_ACCESS_TOKEN_EXPIRES=timedelta(hours=2),
)
if test_config is None:
# load the instance config, if it exists, when not testing
app.config.from_pyfile("config.py", silent=True)
else:
# load the test config if passed in
app.config.from_mapping(test_config)
jwt = JWTManager(app)
"""
Adding blueprints
"""
from app.routes import tester
from app.routes import auth
from app.routes import api_routes
from app.routes import similar_routes
app.register_blueprint(tester.bp)
app.register_blueprint(auth.bp)
app.register_blueprint(api_routes.bp)
app.register_blueprint(similar_routes.bp)
#app.before_request
def check_login():
"""Before each request check if token exist."""
pass
logger.info("Checking if token is required")
if (not getattr(app.view_functions[flask.request.endpoint], "is_public", False)):
logger.info("Token required")
try:
result = verify_jwt_in_request(locations="headers")
logger.debug(f"Identity sent in is {get_jwt_identity()}")
except Exception as e:
logger.error("Error occured during checking token")
logger.error(e)
return jsonify(msg="Token Expired"),401
#app.errorhandler(Exception)
def all_exception_handler(error):
logger.error("Error caught" + str(error) )
return jsonify(msg="Oh no! A Server error occured. :,( "), 500
return app
if __name__ == "__main__":
loggingSetup()
app = create_app()
logger.info("App Created")
app.run(debug=True)
logger.info("App Running")
I'm making API calls from my react frontend, using axios
axios.defaults.baseURL = "http://localhost:5000/api"
function getHeaders(token){
return {
'Accept': 'application/json',
'Content-Type': 'application/json;charset=UTF-8',
"Authorization": "Bearer " + token,
'Access-Control-Allow-Origin': '*'
}
}
async function createCustomObject(token) {
let url = "/ontology/create-object";
let options = {
method: "POST",
url: url,
headers: getHeaders(token),
};
let response = await axios(options).then((response) => {
let data = response.data
}).catch((error) => {
handleError(error.response)
})
return response;
What am I missing?
You would set your origin to http://localhost:3000:
cors = CORS(app, resources={r"/api": {"origins": "http://localhost:3000"}})
'Access-Control-Allow-Origin': 'http://localhost:3000'
I resolved my issue using proxy after trying a couple of failed attempts using CORS solution.
I simply put "proxy": "http://127.0.0.1:5000" in my package.json and therefore, I can then use
fetch(`/test`)
.then((res) => res.json())
.then((data) => {
//do something
});
easily in my app without actually providing the full url to the backend (http://127.0.0.1:5000).
I'm getting an unexpected 403 with trying to upload a file to S3. The weird part is that I have accomplished this before when I did this using the Java AWS SDK to generate the presigned url. I am now using the Python AWS SDK to generate the presigned url and I feel like I am doing the exact same thing.
Here is my code that WORKS no problem:
public UploadSignedRequest getUploadSignedRequest() {
AmazonS3 s3Client = getS3Client();
// Set the pre-signed URL to expire after one hour.
Date expiration = DateUtil.getSignedUrlExpirationDate();
// Generate the pre-signed URL.
String objectKey = UUID.randomUUID().toString();
GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(BUCKET_NAME, objectKey)
.withMethod(HttpMethod.PUT)
.withExpiration(expiration);
String s3FilePath = String.format("%s/%s/%s", S3_URL, BUCKET_NAME, objectKey);
URL signedRequest = s3Client.generatePresignedUrl(generatePresignedUrlRequest);
return new UploadSignedRequest(signedRequest, s3FilePath, objectKey);
}
Here is the successful client code:
var config = {
onUploadProgress: function (progressEvent) {
var percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
updateProgressFunc(percentCompleted);
}
};
axios
.put(signedRequest.signedRequestUrl, videoFile, config)
.then(res => {
console.log(res);
console.log(res.status);
// save video metadata in db
dispatch(saveVideoMetadata(video));
})
.catch(function (error) {
console.log(error);
});
Now, here is me trying to accomplish essentially the same thing (image files instead of video files) using the Python AWS SDK.
def getS3UploadRequest(uuid):
return S3.generate_presigned_url(
ClientMethod='put_object',
Params={
'Bucket': BUCKET,
'Key': uuid
}
)
client code where I get the 403:
axios
.put(signedRequest, attachedFile)
.then(res => {
console.log("successfully uploaded file to s3");
console.log(res);
// dispatch(createProjectTaskComment(newComment, projectTaskId, userId, isFreelancer));
});
When I try to use the presignedUrl in postman, I get the following response back:
?xml version="1.0" encoding="UTF-8"?>
<Error><Code>SignatureDoesNotMatch</Code><Message>The request
signature we calculated does not match the signature you provided.
Check your key and signing method.</Message>
<AWSAccessKeyId>gibberish</AWSAccessKeyId><StringToSign>PUT
Thanks for the help!!!
I have a simple react app. I've added react-fine-uploader to it. I have a Flask server that accepts files and puts them into MongoDB database. The code for server looks like this:
from flask import Flask, render_template, request
from pymongo import MongoClient
import os
import time
from json import dumps, loads
app = Flask(__name__)
global index
map_dir = 'maps'
client = MongoClient(
'<connection_string>')
db = client.business
#app.route('/maps', methods=['GET'])
def process():
cursor = db.maps.find({}, {'_id': False})
maps = {'maps': []}
for doc in cursor:
try:
maps['maps'].append(doc['filename'])
except Exception:
pass
return dumps(maps)
#app.route('/map/<map_name>', methods=['GET'])
def get_map(map_name):
doc = db.maps.find_one({'filename': map_name}, {'_id': False})
return dumps(doc)
#app.route('/uploader', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
f = request.files['file']
parsed = loads(f.read())
filename = ''.join(f.filename.split('.')[:-1]) + str(index) + '.json'
parsed['filename'] = filename
try:
result = db.maps.insert_one(parsed)
return 'File uploaded successfully'
except Exception:
return 'Error while uploading a file'
if __name__ == '__main__':
global index
index = len(os.listdir('maps')) + 1
app.run(debug=True)
It works with standard HTML input form with specifying target as localhost:5000/uploader. Now I want my fine-uploader form to do the same. In code it looks like this:
const uploader1 = new FineUploader({
options: {
request: {
endpoint: "localhost:5000/uploader"
},
resume: {
enabled: true
},
retry: {
enableAuto: true,
showButton: true
}
}
});
And somewhere in the render() method I got: <Gallery uploader={uploader1} />
Now I can select file, but when it is selected the form tries to upload it and it fails. Server is running and I can see no request on him in the terminal. Is there something I am doing wrong?
#Edit I've enabled debug mode and it throws something like this into dev console:
Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https