Search code examples
reactjsflaskrequesthttp-postform-data

Send a form-data POST request to flask endpoint that will be redirected to other more dedicated endpoint


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

  • [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.