【问题标题】:Angular app not able to communicate with Flask via Socket.IOAngular 应用程序无法通过 Socket.IO 与 Flask 通信
【发布时间】:2023-03-19 16:34:02
【问题描述】:

我正在开发一个涉及通过 SocketIO 与 Flask 通信的 Angular 项目。不幸的是,尽管我已经尝试了所有我能理解的东西,但我是 python 和 Flask 的完整初学者。到目前为止,我已经尝试过涉及 CORS,如代码中所示,以及 Zachary Jacobi 中提到的解决方案

Javascript - No 'Access-Control-Allow-Origin' header is present on the requested resource

但是,我仍然收到错误

CORS 策略已阻止从源“http://localhost:4200”访问“http://localhost:5000/socket.io/?EIO=3&transport=polling&t=NDLi66V”处的 XMLHttpRequest:无“访问权限” -Control-Allow-Origin' 标头存在于请求的资源上。

GET http://localhost:5000/socket.io/?EIO=3&transport=polling&t=NDLi66V net::ERR_FAILED

我使用的 Flask 代码是


from flask import Flask, render_template
from flask_socketio import SocketIO
from flask_cors import CORS
from corsAlt import crossdomain

import json

app = Flask(__name__)
CORS(app)
#app.config['SECRET_KEY'] = 'vnkdjnfjknfl1232#'

socketio = SocketIO(app)

@app.route('/')

@crossdomain(origin='*')

def sessions():
    return render_template('index.html')


def messageReceived(methods=['GET', 'POST']):
    print('message was received!!!')

@socketio.on('my event')
def handle_my_custom_event(json, methods=['GET', 'POST']):
    json["user_name"]='Asad'
    json["user_input"]='My Server'
    print('received my event: ' + str(json))
    socketio.emit('my response', json, callback=messageReceived)


if __name__ == '__main__':
    socketio.run(app, debug=True, host='localhost', port = 5000)

在 Angular 方面,

    import { Sio2service } from '../sio2.service';
        @Component({
      selector: 'app-workout-options',
      templateUrl: 'workout-options.component.html',
      styleUrls: ['../app.component.css']
    })
    export class WorkoutOptionsComponent implements OnDestroy{
        mymessage: string;
        subscription: Subscription;

        @Output() public childEvent = new EventEmitter();
            constructor(private messageService: MessageService, private sio2: Sio2service) {
            this.subscription = this.messageService.getMessage()
            .subscribe(mymessage => {
                this.mymessage = mymessage;
            });
        }
 
        OnInit(){
            this.sio2.messages.subscribe(msg => {
        })
        }
        FupdateParent(exerName:string) {
            this.sio2.sendMsg(exerName);
        }
}

SIO 和 SIO2 代码在哪里

import { Injectable } from '@angular/core';
import * as io from 'socket.io-client';
import { Observable } from 'rxjs/Observable';
import * as Rx from 'rxjs/Rx';
import { environment } from '../environments/environment';
@Injectable({
  providedIn: 'root'
})
export class Sioservice {
 private socket;
  constructor() { }
connect(): Rx.Subject<MessageEvent> {
    // If you aren't familiar with environment variables then
    // you can hard code `environment.ws_url` as `http://localhost:5000`
    this.socket = io(environment.ws_url);

    // We define our observable which will observe any incoming messages
    // from our socket.io server.
    let observable = new Observable(observer => {
        this.socket.on('message', (data) => {
          console.log("Received message from Websocket Server")
          observer.next(data);
        })
        return () => {
          this.socket.disconnect();
        }
    });

    // We define our Observer which will listen to messages
    // from our other components and send messages back to our
    // socket server whenever the `next()` method is called.
    let observer = {
        next: (data: Object) => {
            this.socket.emit('message', JSON.stringify(data));
        },
    };

    // we return our Rx.Subject which is a combination
    // of both an observer and observable.
    return Rx.Subject.create(observer, observable);
  }

}

import { Injectable } from '@angular/core';
import { Sioservice } from './sio.service';
import { Observable, Subject } from 'rxjs/Rx';

@Injectable({
  providedIn: 'root'
})
export class Sio2service {

messages: Subject<any>;

  // Our constructor calls our wsService connect method
  constructor(private wsService: Sioservice) {
    this.messages = <Subject<any>>wsService
      .connect()
      .map((response: any): any => {
        return response;
      })
   }

  // Our simplified interface for sending
  // messages back to our socket.io server
  sendMsg(msg) {
    this.messages.next(msg);
  }
}

请注意,Angular 应用与 app.js 文件的通信顺畅


let app = require("express")();
let http = require("http").Server(app);
let io = require("socket.io")(http);

io.on("connection", socket => {
  // Log whenever a user connects
  console.log("user connected");

  // Log whenever a client disconnects from our websocket server
  socket.on("disconnect", function() {
    console.log("user disconnected");
  });

  // When we receive a 'message' event from our client, print out
  // the contents of that message and then echo it back to our client
  // using `io.emit()`
  socket.on("message", message => {
    console.log("Message Received: " + message);
    io.emit("message", { type: "new-message", text: message });
  });
});

// Initialize our websocket server on port 5000
http.listen(5000, () => {
  console.log("started on port 5000");
});

但我遇到的问题是我无法让它与上面的 app.js 通信,因为它似乎创建了自己的服务器。

【问题讨论】:

    标签: node.js angular sockets flask


    【解决方案1】:

    您需要在响应标头中添加三样东西来解决 CORS 问题:

    1. response.headers.add("Access-Control-Allow-Origin", "*")
    2. response.headers.add('Access-Control-Allow-Headers', "*")
    3. response.headers.add('Access-Control-Allow-Methods', "*")

    我不知道 Flask 是如何工作的,但我猜你只处理第 1 点: crossdomain(origin='*')

    旁注:第 3 点用于带有 OPTIONS 动词的飞行前请求。

    为了帮助您,我从您粘贴在问题中的问题链接中复制了部分代码:

    @app.after_request
        def after_request(response):
          response.headers.add('Access-Control-Allow-Origin', '*')
          response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
          response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS')
          return response
    

    【讨论】:

      猜你喜欢
      • 2016-08-30
      • 2015-03-15
      • 1970-01-01
      • 1970-01-01
      • 2011-09-23
      • 2016-05-18
      • 2018-03-31
      • 2011-04-06
      • 1970-01-01
      相关资源
      最近更新 更多