Полное сообщение об ошибке:connect ECONNREFUSED 127.0.0.1:30561 at TCPConnectWrap.afterConnect
Запрос axios выполняется в среде Node.js (Next.js), где и возникает ошибка. Как ни странно, запрос axios работает отлично, когда он выполняется в браузере.
Мой компонент (работающий в Node.js), который вызывает axios:
import axios from 'axios'
import Router from 'next/router'
import React, { Component } from 'react'
import { initializeStore } from '~/reducers'
import { authenticate } from '~/actions/auth'
import { getCookieByName } from '~/helpers/cookie'
const isServer = typeof window === 'undefined'
const __NEXT_REDUX_STORE__ = '__NEXT_REDUX_STORE__'
function getOrCreateStore(initialState) {
// Always make a new store if server, otherwise state is shared between requests
if (isServer) {
return initializeStore(initialState)
}
// Create store if unavailable on the client and set it on the window object
if (!window[__NEXT_REDUX_STORE__]) {
window[__NEXT_REDUX_STORE__] = initializeStore(initialState)
}
return window[__NEXT_REDUX_STORE__]
}
export default App => {
return class AppWithRedux extends Component {
static async getInitialProps(appContext) {
const reduxStore = getOrCreateStore()
appContext.ctx.reduxStore = reduxStore
let appProps = {}
if (typeof App.getInitialProps === 'function') {
appProps = await App.getInitialProps(appContext)
}
const JWT = (isServer ? getCookieByName('JWT', appContext.ctx.req.headers.cookie) : getCookieByName('JWT', document.cookie))
const pathname = appContext.ctx.pathname
//set axios baseURL
axios.defaults.baseURL = (isServer ? `${appContext.ctx.req.headers['x-forwarded-proto']}://${appContext.ctx.req.headers.host}` : window.location.origin)
//if user has a JWT
if(JWT){
axios.defaults.headers.common['Authorization'] = `Bearer ${JWT}`
//get user from API layer
reduxStore.dispatch(authenticate())
}
return {
...appProps,
initialReduxState: reduxStore.getState()
}
}
constructor(props) {
super(props)
this.reduxStore = getOrCreateStore(props.initialReduxState)
}
render() {
return <App {...this.props} reduxStore={this.reduxStore} />
}
}
}
КонкретноreduxStore.dispatch(authenticate())
И мой фактический вызов axios (использующий redux thunk), глядя на authenticate
метод:
import axios from 'axios'
import { setCookieByName } from '~/helpers/cookie'
const BASE_URL = '/api/auth'
export const TYPE_REGISTER = 'TYPE_REGISTER'
export const TYPE_AUTHENTICATE = 'TYPE_AUTHENTICATE'
export const register = values => (dispatch) => {
return axios.post(`${BASE_URL}/register`, values)
.then(function({data: {token, user}}){
setCookieByName('JWT', token, 365)
dispatch({
type: TYPE_REGISTER,
payload: user
})
})
}
export const authenticate = () => (dispatch) => {
return axios.post(`${BASE_URL}/me`)
.then(function({data: {user}}){
dispatch({
type: TYPE_AUTHENTICATE,
payload: user
})
})
.catch(function(err){
console.log(err)
dispatch({
type: TYPE_AUTHENTICATE,
payload: {}
})
})
}
Я запускаю свой локальный кластер Kubernetes с помощью Docker для Mac, и мой контроллер Ingress доступен на http://kludge.info:30561
. Мой домен сопоставлен 127.0.0.1 kludge.info
локально, чтобы контроллер Ingress мог обращаться к контейнеру. Моя теория заключается в том, что когда я отправляю запрос, http://kludge.info:30561/api/auth/me
например, контейнер Docker, на котором запущено приложение Node.js, думает, что это запрос к localhost (внутри контейнера), и приводит к ошибке подключения. Обратите внимание, что приложение Node.js внутри контейнера работает на http://localhost:8080
. По сути, я запускаю localhost на своей машине и localhost внутри экземпляра Node. Как я могу отправить запрос наружу, туда, http://kludge.info:30561/
где запущен контроллер Ingress.
Я также настроил baseURL
in axios, но это не решает проблему. У моего ingress-контроллера есть путь /api
, который будет указывать на экземпляр PHP, поэтому мне нужно, чтобы мой вызов Node.js axios попал туда внутри его контейнера. Любая помощь будет оценена по достоинству.
Когда я запускал свой кластер K8 на Minikube, у меня не возникало этой проблемы, однако minikube предоставляет вам IP-адрес виртуальной машины, в то время как Docker для рабочего стола использует его localhost
непосредственно на вашей машине.