python ajax - Comment puis-je envoyer une demande GET de mon application flacon à un autre site?




call flask (4)

Installez le module de requests (beaucoup plus agréable que d'utiliser urllib2 ), puis définissez une route qui fait la demande nécessaire - quelque chose comme:

import requests
from flask import Flask
app = Flask(__name__)

@app.route('/some-url')
def get_data():
    return requests.get('http://example.com').content

En fonction de votre configuration, il vaudrait mieux configurer votre serveur Web pour qu'il inverse le proxy vers le site cible sous une certaine URL.

À l'origine, j'ai essayé de poster une requête ajax de mon côté client vers une URL tierce, mais il semble que le navigateur a des problèmes de sécurité avec cela. J'ai pensé à envoyer un ajax du côté du serveur, à partir de là pour envoyer une requête GET au tiers, obtenir la réponse et la renvoyer au client. Comment puis-je faire ça avec un flacon?


Flask seul n'a pas cette capacité, mais il est simple d'écrire un gestionnaire de requêtes qui fait une demande à un autre serveur en utilisant une bibliothèque cliente HTTP, puis retourne cette réponse.

# third-party HTTP client library
import requests

# assume that "app" below is your flask app, and that
# "Response" is imported from flask.

@app.route("/proxy-example")
def proxy_example():
    r = requests.get("http://example.com/other-endpoint")
    return Response(
        r.text
        status=r.status_code,
        content_type=r.headers['content-type'],
    )

Cependant, cela n'obtiendra pas exactement le même résultat que vous pourriez attendre d'une requête côté client. Comme votre serveur ne peut pas "voir" les cookies que le navigateur client a stockés pour le site cible, votre requête proxy sera effectivement anonyme et, selon le site cible, peut échouer ou vous donner une réponse différente de celle que vous obtiendriez. cette ressource dans le navigateur.

Si vous avez une relation avec l'URL tierce (c'est-à-dire, si vous la contrôlez ou êtes capable de travailler avec les personnes qui le font), elle peut accéder aux requêtes interdomaines dans le navigateur à l'aide de CORS navigateurs modernes) ou JSON-P (une ancienne solution de contournement antérieure à CORS).

Le fournisseur tiers peut également vous donner accès aux données que vous souhaitez à un point de terminaison conçu pour accepter les demandes provenant d'autres serveurs et qui fournit un mécanisme pour vous permettre d'authentifier votre application. Le protocole le plus populaire pour cela est OAuth .


Comme l'ont indiqué les autres réponses, l'utilisation du module de requêtes pour python serait le meilleur moyen d'y remédier du point de vue du codage. Cependant, comme les commentaires mentionnés (et la raison pour laquelle je suis arrivé à cette question) cela peut donner une erreur que la demande a été refusée. Cette erreur est probablement due à SELinux.

Pour vérifier si c'est le problème, vérifiez d'abord que SELinux est activé avec cette commande:

sestatus

Si le 'mode actuel' est 'appliqué', alors SELinux est activé.

Ensuite, obtenez les valeurs de boolos actuelles qui s'appliquent directement à Apache avec cette commande:

getsebool -a | grep httpd

Recherchez le paramètre 'httpd_can_network_connect' qui détermine si apache est autorisé à faire des requêtes TCP sur le réseau. Si c'est le cas, toutes les requêtes TCP apache seront autorisées. Pour l'activer, exécutez ce qui suit en tant que root:

setsebool -P httpd_can_network_connect 1

Si vous avez seulement besoin d'un accès à la base de données (j'ai déjà eu ce problème et pourquoi j'ai suspecté SELinux ici) alors il vaudrait probablement mieux activer 'httpd_cna_network_connect'.

Le but de cette politique est que si un pirate devait pirater votre serveur apache, il ne serait pas capable de sortir du serveur vers le reste de votre réseau interne.

Cela aurait probablement été mieux comme un commentaire, mais je n'ai pas assez de rep ..

Sources: https://tag1consulting.com/blog/stop-disabling-selinux https://wiki.centos.org/TipsAndTricks/SelinuxBooleans


Fonctionne parfaitement avec python 3.5+

client:

import requests
data = {'sender':   'Alice',
    'receiver': 'Bob',
    'message':  'We did it!'}
r = requests.post("http://localhost:8080", json={'json_payload': data})

serveur:

class Root(object):

    def __init__(self, content):
        self.content = content
        print self.content  # this works

    exposed = True

    def GET(self):
        cherrypy.response.headers['Content-Type'] = 'application/json'
        return simplejson.dumps(self.content)

    @cherrypy.tools.json_in()
    @cherrypy.tools.json_out()
    def POST(self):
        self.content = cherrypy.request.json
        return {'status': 'success', 'message': 'updated'}




python ajax flask