I'm trying to create a more general endpoint for handling upload files. This endpoint will check the file and based on the file's type will redirect to a specific endpoint (dedicated for a specific file type upload). To test this idea, on the client side(reactJS) I enabled redirect: 'follow'
on fetch and on the flask side, I added HTTP code 307
to preserve the request. I used the browser to access the path (using GET), the redirect works. but when using the react app, the fetch seems that doesn't follow the redirect, because the app receives the 307 from the provided endpoint but doesn't receive the 200 code from the redirect.
Server log:
# Using Browser
127.0.0.1 - - [06/Apr/2021 16:28:08] "GET /upload/shp HTTP/1.1" 307 -
Redirect request received!
127.0.0.1 - - [06/Apr/2021 16:28:08] "GET /upload/redirect HTTP/1.1" 200 -
# Using React App
127.0.0.1 - - [06/Apr/2021 16:33:22] "POST /upload/shp HTTP/1.1" 307 -
The client side - ReactJS:
uploadAPI = async (formData) => {
fetch(API_SERVER_URL + this.state.destpath, {
method: "post",
redirect: 'follow',
body: formData,
config: { headers: { "Content-Type": "multipart/form-data" } },
}).then((res) => {
if (res.ok) {
alert("File uploaded successfully.");
}
});
};
The server side - Flask:
@app.route('/upload/redirect', methods = ['POST', 'GET'])
def index():
print("Redirect request received!")
return "redirect", 200, {'Content-Type': 'application/json'}
@app.route('/upload/shp', methods = ['POST', 'GET'])
def file_recv_shp_node():
""" API endpoint that receives a zip with shp,sbf,shx files
This endpoint receives a file via FormData only by a `POST` request
Args:
no value
Returns:
Returns json object with the number of created/updated data
"""
return redirect(url_for('index'),code=307)
UPDATE 1 I found that request is failing on the side of reactJS. I added the following code to see what was happening:
.then((res) => {
console.log("request", res)
if (res.ok) {
alert("File uploaded successfully.");
}
Console JS log:
> Import.js:168 POST http://0.0.0.0:5001/upload/shp net::ERR_CONNECTION_RESET
> localhost/:1 Uncaught (in promise) TypeError: Failed to fetch
UPDATE 2
uploadNeo4jAPI = async (formData) => {
fetch(API_SERVER_URL + this.state.destpath, {
method: "post",
redirect: 'follow',
body: formData,
mode: 'cors',
redirect: 'follow',
keepalive: true,
config: { headers: { "Content-Type": "multipart/form-data" } },
}).then((res) => {
console.log("request", res)
if (res.ok) {
alert("File uploaded successfully.");
}
});
};
@app.route('/upload/redirect',methods = ['POST', 'GET'])
@cross_origin()
def index():
print("Redirect request received!")
return "redirect", 200, {'Content-Type': 'application/json'}
@app.route('/upload/shp', methods = ['POST', 'GET'])
@cross_origin()
def file_recv_shp_node():
""" API endpoint that receives a zip with shp,sbf,shx files
This endpoint receives a file via FormData only by a `POST` request
Args:
no value
Returns:
Returns json object with the number of created/updated data
"""
return redirect(url_for('index'),code=307)
I tried to allow CORS
explicit but it doesn't work either.
[SOLUTION]
A solution that works, in this case, is calling the function directly on the main endpoint instead of using a redirect to the related endpoint. The request and form-data is also reachable without the need of passing as function arguments.