Сбои CORS при использовании контейнеров Docker для внешнего интерфейса и внутреннего интерфейса - PullRequest
0 голосов
/ 13 сентября 2018

Следующий код отлично работает вне контейнеров Docker. Теперь я хотел бы добавить контейнер для бэкэнда и еще один для внешнего интерфейса. Поэтому я создаю два файла Docker (которые, вероятно, неинтересны) и следующий файл docker-compose. Я изменяю axios.get('http://127.0.0.1:5000/api/test') на axios.get('http://backend:80/api/test') в компоненте vue. Я могу пропинговать контейнер backend из контейнера frontend, и я могу получить результат API через curl. Но axios больше не может сделать этот запрос API. И в консоли Firefox я получаю ошибку:

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

Но я могу запустить серверную часть внешнего докера на одном компьютере в моей сети и на другом. Так что Cross-Origin не проблема вне докера. В чем здесь проблема? Понятия не имею.


докер-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>

1 Ответ

0 голосов
/ 13 сентября 2018

Может показаться, что вы ошибаетесь, когда ссылаетесь на контейнеры-докеры вне всех контейнеров.

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

Следует указать, где находится контейнер-докер.Внутри контейнера это действительно будет backend, но снаружи, т.е. в вашем веб-браузере, это будет ссылка на хост, на котором запущен контейнер, за которым следует порт.Так как вы установили его на порт 80 на хосте (и на 90 для внешнего интерфейса), вы должны обновить get до:

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

Если он работает на одном хосте, то вы можетеиспользуйте для тестирования 127.0.0.1 или localhost.

...