-1

Tried everything but the response doesn't get through! I can't find where I am wrong!

I have trouble with the fetch request. It's quite not working properly with FLASK localhost. I put a simple get request but all I get is an opaque response while logging on console. Though, just by going on the api endpoint, I am able to see the response.

.py(flask localhost)

from flask import Flask, render_template, request, jsonify
from flask_cors import CORS, cross_origin

app = Flask(__name__)

@app.route('/findHotels',methods = ['GET','POST'])
@cross_origin()
def findHotelsHelper():
    if request.method == 'GET':
        response = jsonify(message="Simple server is running")
        response.headers.add("Access-Control-Allow-Origin", "*")
        return response

if __name__ == '__main__':
    app.run(debug = True)

following is the code for html which is requesting data using fetch api

<!DOCTYPE html>
<html>
<body>
  <h1>Find Nearest Hotels in your Area! </h1>
  
  <form id="form1" action="http://localhost:5000/findHotels" method="GET">
      First name: <input type="text" name="fname"><br>
      Last name: <input type="text" name="lname"><br><br>
      <input type="button" onclick="loadDoc()" value = "GO">
  </form>
  
  <p id="demo"></p>
  
  <script>
  
      
  async function loadDoc(){
      await fetch('http://127.0.0.1:5000/findHotels', { method: 'GET', mode:'no-cors'})
          .then(function (response) {
            console.log(response);
            return response;
          }).then(function (text) {
            console.log('GET response:');
            console.log(text); 
          });
  }
  </script>
  
  </body>
</html>

Any suggestions would be very much appreciated. P.S. Sorry, I am new to stack overflow, forgive for not following proper rules for a post this while. Image showing working get request Image showing failed/(getting opaque) request if using fetch api Also I would like to point out, simple forms were also working fine and I was able to retrieve the json data but I want to do it without it and using JS only.

2 Answers2

0

The Ajax request is sending a POST request so you should change the portion of your Python code to match that method.

from flask import Flask, render_template, request, jsonify
from flask_cors import CORS, cross_origin

app = Flask(__name__)

@app.route( '/findHotels', methods = ['GET','POST'] )
@cross_origin()
def findHotelsHelper():
    if request.method == 'POST':
        response = jsonify(message="Simple server is running")
        response.headers.add("Access-Control-Allow-Origin", "*")
        return response

if __name__ == '__main__':
    app.run(debug = True)

Assuming that the Python code is sending plain text as a response then, within the fetch call chain, you should return the text value - ie: response.text()

<form name='search' action='http://localhost:5000/findHotels' method='GET'>
    First name: <input type='text' name='fname'><br>
    Last name: <input type='text' name='lname'><br><br>
    <input type='button' value='GO' />
</form>

<p id='demo'></p>

<script>

    async function loadDoc(e){
        await fetch( oForm.action, { method: 'POST', mode:'no-cors' })
            .then( r=>r.text() ) // return the `text()` property
            .then( text=>{
                console.log('GET response:%s',text);
            })
    }
    
    let oForm=document.forms.search;
    let oBttn=oForm.querySelector('input[type="button"]');
        oBttn.addEventListener('click',loadDoc);
    


</script>

Without Python to test I quickly knocked up a PHP version of the above. This works absolutely fine so perhaps the issue lies in the Python code?!

<?php
    if( $_SERVER['REQUEST_METHOD']=='POST' ){
        ob_clean();
        header('Access-Control-Allow-Origin','*');
        $message="Simple server is running";
        exit($message);
    }
?>
<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8' />
        <title></title>
        <script>
            document.addEventListener('DOMContentLoaded',(e)=>{
            
                async function loadDoc(e){
                    await fetch( oForm.action, { method:'POST', mode:'no-cors' })
                        .then( r=>r.text() ) // return the `text()` property
                        .then( text=>{
                            console.log('POST response:%s',text);
                            alert( text )
                        })
                }
                
                let oForm=document.forms.search;
                let oBttn=oForm.querySelector('input[type="button"]');
                    oBttn.addEventListener('click',loadDoc);
                
            })
        </script>
    </head>
    <body>
        <form name='search' method='GET' action=''>
            First name: <input type='text' name='fname' />
            Last name: <input type='text' name='lname' />
            <input type='button' value='GO' />
        </form>
    </body>
</html>
Professor Abronsius
  • 33,063
  • 5
  • 32
  • 46
  • Yeah fixed it, yet again typo, because I was trying to get any of the methods work. In hurry, I did that, but I have fixed it, tried to write the exact code you have mentioned, it still gives the opaque response on fetch but works on normal get by browser. Thank you for looking so carefully. Excuse me once again. – Vedant Vijay Apr 03 '21 at 09:19
0

You have mode: 'no-cors' in your fetch options. According to https://developer.mozilla.org/en-US/docs/Web/API/Request/mode it gives opaque responses.

Since your server is capable of sending CORS headers, you should set mode: 'cors'.

<!DOCTYPE html>
<html>
<body>
  <h1>Find Nearest Hotels in your Area! </h1>
  
  <form id="form1" action="http://localhost:5000/findHotels" method="GET">
      First name: <input type="text" name="fname"><br>
      Last name: <input type="text" name="lname"><br><br>
      <input type="button" onclick="loadDoc()" value = "GO">
  </form>
  
  <p id="demo"></p>
  
  <script>
  
      
  async function loadDoc(){
      await fetch('http://127.0.0.1:5000/findHotels', { method: 'GET', mode:'cors'})
          .then(function (response) {
            console.log(response);
            return response;
          }).then(function (text) {
            console.log('GET response:');
            console.log(text); 
          });
  }
  </script>
  
  </body>
</html>
Anton
  • 440
  • 3
  • 10
  • Okay, I think I should look into this, It worked amazing! Thanks a lot, I'll spend my time understanding the underlying concept, I was just trying to get pass this while, my bad. Thank you once again. – Vedant Vijay Apr 03 '21 at 10:18