Ricerca nel sito web

Come collegare il backend (python, flask) con il frontend (html, css, javascript)


Info: per il backend sto usando Python con Flask (per il momento accetta metodi http get) e per il frontend sto usando HTML, CSS e JavaScript.

Problema: Sto cercando di fare una richiesta http (la prima volta ho provato POST e poi GET) ma il browser non me lo ha permesso: "Accesso a XMLHttpRequest su 'localhost:5000/test' dall'origine 'null' è stato bloccato dalla politica CORS: Le richieste cross-origin sono supportate solo per schemi di protocollo: http, data, chrome, chrome-extension, https.".

Quali altre scelte ho? (Vorrei alcune scelte semplici, è solo un compito).

Ho provato a fare richieste HTTP POST e GET. Ho letto che non posso fare richieste HTTP dal browser. Ho letto che ho bisogno (per esempio) di un server Apache. - troppo complicato, ho bisogno di qualcosa di più semplice. Ho provato: https://flask-cors.readthedocs.io/en/latest/

document.getElementById("btn").addEventListener('click', add);
function add()
{
    const url = "localhost:5000/test";
    const http = new XMLHttpRequest();
    http.open("GET", url);
    http.send();
    http.onreadystatechange=(e)=> {
        console.log(http.responseText)
    }
}
from flask import Flask
from flask_cors import CORS
from flask import request
from flask import jsonify
import json
import mysql.connector
import random
import string
import time

time.sleep(3)
app = Flask(__name__)

@app.route("/test")
def test():
    return "It's working"


if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5000)

Mi aspetto che nella console del browser venga stampato il messaggio: "Funziona", ma ricevo l'errore: Accesso a XMLHttpRequest su 'localhost:5000/test' dall'origine 'null' è stato bloccato dalla politica CORS: Le richieste cross-origin sono supportate solo per schemi di protocollo: http, data, chrome, chrome-extension, https.

LE: Il server Flask è all'interno di un contenitore Docker. Le porte sono mappate "5000:5000".

Risposta n. 1

Se stai usando la stessa macchina, non è necessario usare flask-cors.

Aggiornamento: Poiché stai usando Docker, puoi usare flask-cors per gestire i CORS.

Ho scoperto che le chiamate AJAX non erano corrette nel tuo codice JS. const url="localhost:5000/test"; non fornisce informazioni sul protocollo della richiesta.

Ho seguito questi passaggi per eseguire con successo un'applicazione Flask usando Docker e accedere all'endpoint /test usando JS al di fuori di Docker.

  • Ho aggiornato la richiesta AJAX
  • Aggiunto Dockerfile per eseguire l'applicazione Flask all'interno di Docker
  • Costruisci ed esegui il Dockerfile
  • Ottieni l'indirizzo IP del container Docker in esecuzione.
  • Ho utilizzato l'indirizzo IP nella chiamata AJAX nel codice JS che è fuori da Docker.

Struttura delle cartelle:

.
├── backend.py
├── Dockerfile
├── readme.md
└── requirements.txt

requirements.txt:

Flask==1.0.2
Flask-Cors==3.0.7

Dockerfile:

FROM python:3
ENV PYTHONBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/
CMD ["python", "backend.py" ]

Crea file Docker:

docker build -t flask-docker .

Esegui Docker:

docker run -p 5000:5000 flask-docker

* Serving Flask app "backend" (lazy loading)
* Environment: production
  WARNING: Do not use the development server in a production environment.
  Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

Ottieni l'ID del container Docker:

docker ps

CONTAINER ID        IMAGE                   COMMAND                CREATED             STATUS              PORTS                    NAMES
69cb7d5d243a        flask-docker            "python backend.py"    15 minutes ago      Up 15 minutes       0.0.0.0:5000->5000/tcp

Ottieni l'indirizzo IP del container Docker:

docker inspect --format '{{ .NetworkSettings.IPAddress }}' 69cb7d5d243a  

172.17.0.2

Usa questo indirizzo IP nella richiesta AJAX nel file HTML:

<html>
<head>
  <title>Frontend</title>
</head>
<body>
  <div id="data"></div>
  <button type="button" id="btn">Grab data</button>
  <script type="text/javascript">
  document.getElementById("btn").addEventListener('click', add);
  function add()
  {
    const api_url = "http://172.17.0.2:5000/test";
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        document.getElementById("data").append(this.responseText);
      }
    };
    xhttp.open("GET", api_url, true);
    xhttp.send();
  }
  </script>
</body>
</html>  

backend.py:

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


app = Flask(__name__)
CORS(app)    

@app.route("/test")
def test():
    return "It's working"    

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5000)

Output:

Risposta n. 2

Aggiungi la seguente riga sotto app=Flask(__name__):

CORS(app)

Dai un'occhiata al semplice utilizzo di flask-cors