将Docker容器用于前端和后端时CORS失败

时间:2018-09-13 08:24:13

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

以下代码在docker容器外部运行良好。现在,我想为后端添加一个容器,为叶形添加另一个容器。因此,我创建了两个Dockerfile(可能没有意思)和以下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外部运行后端,而在另一台计算机上运行前端。因此,跨源在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)

朋友(仅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>

2 个答案:

答案 0 :(得分:4)

您似乎在误导如何从所有容器外部引用Docker容器。

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

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

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

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

答案 1 :(得分:0)

您可以在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')