【问题标题】:CORS failes when using Docker containers for frontend and backend将 Docker 容器用于前端和后端时,CORS 失败
【发布时间】:2019-02-17 22:36:36
【问题描述】:

以下代码在 docker 容器之外运行良好。现在我想为后端添加一个容器,为前端添加另一个容器。所以我创建了两个 Dockerfiles(这可能是无趣的)和下面的 docker-compose 文件。我在 vue 组件中将axios.get('http://127.0.0.1:5000/api/test') 更改为axios.get('http://backend:80/api/test')。我能够从前端容器 ping 后端容器,并且能够通过 curl 接收 api 结果。 但是 axios 不能再发出这个 api 请求了。在 Firefox 控制台中我得到错误:

Error: "Network Error"
Cross-Origin request blocked [...] Reason: CORS request did not succeed

但我可以在我网络中的一台计算机上运行 docker 外部的后端,而在另一台计算机上运行前端。所以Cross-Origin在docker之外是没有问题的。 这里有什么问题?我不知道。


docker-compose.yml

version: '2'
services:
    backend:
        build: ./backend
        container_name: backend
        ports:
          - "80:80"
        environment:
          - FLASK_APP=app/main.py
          - FLASK_DEBUG=1
          - 'RUN=flask run --host=0.0.0.0 --port=80'
        networks:
          - some-net

    frontend:
        build: ./frontend
        container_name: frontend
        ports:
          - "90:80"
        networks:
          - some-net

networks:
    some-net:
        driver: bridge

原代码

python 中的后端

from flask import Flask, jsonify
from flask_cors import CORS

app = Flask(__name__)
CORS(app, resources=r'/api/*')

@app.route('/api/test')
def test():
    return jsonify({
        "foo": "bar"
    })

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

frondend(仅 vue.js 组件)

<template>
<div class="hello">
    <h1>Message is: {{ msg }}</h1>
</div>
</template>

<script>
import axios from 'axios'

export default {
name: 'HelloWorld',
data () {
    return {
        msg: ''
    }
},
created () {
    axios.get('http://127.0.0.1:5000/api/test').then(response => {
        console.log(response.data)
        this.msg = response.data.foo
    }).catch(error => {
        console.log(error)
    })
}
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>

【问题讨论】:

  • 您是否尝试过使用 @cross_origin() 装饰器(如 flask_cors 文档中所示)用于特定路线,而不是使用 CORS 对象?我只是好奇这是否也失败了
  • 这似乎与 docker setup 有关,因为它在外部工作。您是在使用浏览器访问前端服务,然后是后端服务吗?
  • @NeilTwist 是的,我已经发布了前端容器的端口 90 并使用 firefox 访问 127.0.0.1:90。我在控制台中收到错误消息。
  • 好的,那请看我的回答。

标签: python docker vue.js cors docker-compose


【解决方案1】:

您似乎误会了如何从所有容器外部引用 docker 容器。

axios.get('http://127.0.0.1:5000/api/test')...

应该指 docker 容器正在监听的位置。在容器内部,这确实是backend,但在外部,即在您的 Web 浏览器中,它将是对运行容器的主机的引用,然后是端口。由于您已将其安装在主机的 80 端口(前端为 90),您应该将get 更新为:

axios.get('http://{hostname or ip}:80/api/test')

如果它们都在同一主机上运行,​​那么您可以使用127.0.0.1 或 localhost 进行测试。

【讨论】:

  • 前端容器应该与后端容器通信,所以我使用主机名backend,因为两个容器都使用桥接网络。
  • 是的,我可以看到

    消息是:

    但由于 cors 错误,消息无法加载
  • Firefox中的错误意味着该错误发生在Firefox中?你能在开发者控制台中看到网络标签吗?
  • 没有我在控制台中看到的错误来自使用console.log(error)记录axios错误的前端
  • 所以,你可以看到请求来自Firefox,所以请求的参考框架是浏览器,这意味着你需要从docker外部引用服务。
【解决方案2】:

您可以在 docker-compose.yaml 中使用“链接”。所以它看起来像这样:

xxxdjango:
    image: xxx_django:dev
    ports:
      - "8000:80"
xxx_ui:
    image: xxx_ui:dev
    volumes:
       - ./xxx_ui/src:/app/src
       - ./xxx_ui/public:/app/public
    ports:
      - "8080:8080"
    links:
      - xxxdjango

所以在这之后,你可以使用 Vue js

devServer: {
   proxy: 'http://xxxdjango'
}

axios.get('/api/test')

【讨论】:

    猜你喜欢
    • 2020-09-13
    • 1970-01-01
    • 2017-09-03
    • 1970-01-01
    • 2021-12-15
    • 2020-07-27
    • 1970-01-01
    • 2020-03-19
    • 2020-03-05
    相关资源
    最近更新 更多