aiohttp-cors

Le problème exposé dans ce sujet a été résolu.

Bonjour

J’ai ce code qui me permet d’établir une connexion websoket.

from aiohttp import web
routes = web.RouteTableDef()
 
ws = None
@routes.get("/ws")
async def websocket(request):
    global ws
    ws = Websocket(request)
    print("Connected")
    await ws
    print("Disconnected")
    return ws.ws
 
@routes.post("/connect")
async def connect(request):
    global ws
    if ws is None:
        raise web.HTTPInternalServerError("There is no connected")
    clientOffer = await request.json()
    ws.put_nowait(clientOffer)
    Response = await ws.get()
    return web.json_response(Response)
 
async def cleanup(app=None):
    global ws
    if ws is not None:
        c = ws.close()
        if c is not None:
            await c
 
app = web.Application()
app.add_routes(routes)
app.on_shutdown.append(cleanup)
web.run_app(app,host='xx.xx.xx.xx', port=5000)

Il marche bien en local mais si je tente de le joindre depuis une page web externe j’ai un erreur de ce type

Access to fetch at 'https://unautre.site' from origin 'https://mon.site' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Après pas mal de recherche je suis tomber sur aiohttp-cors mais j’ai besoin d’aide pour l’ajouter à mon code.

+0 -0

Comme cela a été évoqué dans un précédent sujet, il est impératif que ce soit le serveur HTTP de https://unautre.site qui expose les headers Access-Control-Allow-Origin adéquats. Si tu n’as pas le contrôle sur ce serveur, alors tu ne peux pas définir ces headers nécessaires pour que le navigateur accepte la liaison WS sans broncher. En revanche, si tu contrôles le serveur, il te suffit de mettre le header comme cela : Access-Control-Allow-Origin: https://mon.site ou bien Access-Control-Allow-Origin: * pour tout accepter (à éviter si possible, mais ça dépend du cas).

Pourquoi ne pas faire tourner ton code client sur la même origine que ton backend ? (accéder en WS à https://mon.site depuis l’origine https://mon.site). Ça t’éviterait de te confronter au CORS.

Autre point, qui n’a rien à voir avec ta question.

Pourquoi utilises-tu un object ws global ? Il me semble que la documentation ne préconise pas cela, mais plutôt de définir chaque object websocket de façon locale dans sa coroutine :

async def ws_get_messages(req):
    ws = web.WebSocketResponse()
    await ws.prepare(req)
    [ ... ]
    return ws

@entwanne : Cela te semble évident mais c’est justement ce que je n’arrive pas a faire :honte:

@sgble : Dans mon autre post j’ai bien compris que le site que je voulais joindre n’était pas bien paramétré et je n’ais pas la mains dessus.

J’essais donc cette autre méthode sur mon propre serveur: mon site sur apache/php qui affiche une page web (port 80) avec du js qui tente de réaliser une connexion websoket. Et ce script python sur le port 5000

J’ai donc la main sur ce script mais je n’arrive pas a faire passer les Headers

J’aurai bien voulu tous faire en php sur le même port mais je n’ai pas trouve de documentions accessible a mon niveau.

Pourquoi utilises-tu un object ws global ?

Parce-que c’est ce que j’ai trouvé et que sa fonctionne.

Dison que je code en amateur une "preuve de concept" et que l’optimisation de tous ceci sera faite bien plus tard par un pro.

+0 -0

J’ai trouvé une solution qui fonctionne :magicien: :

app = web.Application()
app.add_routes(routes)

app = web.Application()
app.add_routes(routes)

cors = aiohttp_cors.setup(app, defaults={
    "*": aiohttp_cors.ResourceOptions(
            allow_credentials=True,
            expose_headers="*",
            allow_headers="*",
        )
})

for route in list(app.router.routes()):
    cors.add(route)


app.on_shutdown.append(cleanup)
+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte