I have a NextJS web app and NestJS backend. Locally with npm run dev or npm run build && npm start all works fine.
But deployed app (front and back in docker on different servers) not updating data on groups page.
When I build my app it generates a page with data from backend. Then I can add a new group (just new data), return to the group's page and can not see my mewGroup in the list.
My getStaticProps (not working):
export const getStaticProps: GetStaticProps<GroupProps> = async () => {
const { getGroups, getUsers, getModules } = useHttp();
const { data: groups } = await getGroups();
const { data: users } = await getUsers();
const { data: modules } = await getModules();
return {
props: { groups, users, modules },
revalidate: 5
};
};
My post request (working):
createGroup(body)
.then(() => {
push(routes.groups);
})
.catch((error) => {
throwError && throwError(error);
});
Again, it works fine locally even with the production backend.
But production web does not update any info, just can push some.
It's my first NextJS app, but I worked with react.
In my production logs I see the error, but have no idea how to handle it:
Error: getaddrinfo EAI_AGAIN {{MY_BACK_SERVER}}
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:71:26) {
errno: -3001,
code: 'EAI_AGAIN',
syscall: 'getaddrinfo',
hostname: '{{MY_BACK_SERVER}}',
config: {
transitional: {
silentJSONParsing: true,
forcedJSONParsing: true,
clarifyTimeoutError: false
},
adapter: [Function: httpAdapter],
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
validateStatus: [Function: validateStatus],
headers: {
Accept: 'application/json, text/plain, */*',
'User-Agent': 'axios/0.24.0'
},
method: 'get',
url: 'http://{{MY_BACK_SERVER}}:5000/groups',
data: undefined
},
request: <ref *1> Writable {
_writableState: WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
destroyed: false,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: true,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
afterWriteTickInfo: null,
buffered: [],
bufferedIndex: 0,
allBuffers: true,
allNoop: true,
pendingcb: 0,
prefinished: false,
errorEmitted: false,
emitClose: true,
autoDestroy: true,
errored: null,
closed: false
},
_events: [Object: null prototype] {
response: [Function: handleResponse],
error: [Function: handleRequestError]
},
_eventsCount: 2,
_maxListeners: undefined,
_options: {
maxRedirects: 21,
maxBodyLength: 10485760,
protocol: 'http:',
path: '/groups',
method: 'GET',
headers: [Object],
agent: undefined,
agents: [Object],
auth: undefined,
hostname: '{{MY_BACK_SERVER}}',
port: '5000',
nativeProtocols: [Object],
pathname: '/groups'
},
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 0,
_requestBodyBuffers: [],
_onNativeResponse: [Function (anonymous)],
_currentRequest: ClientRequest {
_events: [Object: null prototype],
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: false,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: [Socket],
_header: 'GET /groups HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'User-Agent: axios/0.24.0\r\n' +
'Host: {{MY_BACK_SERVER}}:5000\r\n' +
'Connection: close\r\n' +
'\r\n',
_keepAliveTimeout: 0,
_onPendingData: [Function: noopPendingOutput],
agent: [Agent],
socketPath: undefined,
method: 'GET',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
path: '/groups',
_ended: false,
res: null,
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: '{{MY_BACK_SERVER}}',
protocol: 'http:',
_redirectable: [Circular *1],
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype]
},
_currentUrl: 'http://{{MY_BACK_SERVER}}:5000/groups',
[Symbol(kCapture)]: false
},
response: undefined,
isAxiosError: true,
toJSON: [Function: toJSON]
}
so when you first open the group page it showed you the information from the static file,
there are two cases -
now if there is a modification in the data (ie befor opening the group page for the first time) it will show you the old data (as it works with stale
while revalidate cache) and update the data (in background) for group page
(getStaticProps ). so when you again visit the group page again it
will show you the updated data.
Now the second case is (the one related to you) you opened the group page it checks there is no need to update the page in the
background as there is no new data in the server, it shows you the
data and then you in the same session updated the group info (added a
new data), next js will not show those newly created data because from
here it is serving you pages from the local cache. just because it
doesn't see any update of data in the first render.
You will have to do a full refresh to see the newly created data.
recommendation - use full page refresh occasionally (programmatically) when you think there may be a new data created or user server side rendering.
Thanks
Finally, I solve the problem. My container has no internet connection, SSR just can't ping the backend. POST request works well because it client-side request.
Related
I have currently implemented Auth0 authentication on my NextJS app by following their docs, and am trying to call an external ExpressJS application by following their docs: https://github.com/auth0/nextjs-auth0/blob/main/EXAMPLES.md#access-an-external-api-from-an-api-route.
I have NextJS running on port 3000 and Express running on port 3001.
My express server is set up as follows:
const jwtCheck = expressjwt({
secret: jwksRsa.expressJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: process.env.AUTH0_JWKS_URI as string,
}) as GetVerificationKey,
audience: process.env.AUTH0_AUDIENCE as string,
issuer: process.env.AUTH0_ISSUER as string,
algorithms: ['RS256'],
})
app.use(jwtCheck)
When I try to make an unauthenticated request from my NextJS app to the external API, I get the UnauthorizedError: No authorization token was found error which ensures it is working. If I comment out app.use(jwtCheck) the requests are successful as there is no auth check.
I have my NextJS application set up as follows:
// [...auth0].ts
import { handleAuth, handleLogin } from '#auth0/nextjs-auth0'
export default handleAuth({
login: handleLogin({
authorizationParams: {
audience: process.env.AUTH0_AUDIENCE, // or AUTH0_AUDIENCE
// Add the `offline_access` scope to also get a Refresh Token
scope: 'openid profile email read:trips', // or AUTH0_SCOPE
},
}),
})
// /api/trips.ts
import { getAccessToken, withApiAuthRequired } from '#auth0/nextjs-auth0'
const apiURL = process.env.NEXT_PUBLIC_SERVER_URL
export default withApiAuthRequired(async function trips(req, res) {
// If your access token is expired and you have a refresh token
// `getAccessToken` will fetch you a new one using the `refresh_token` grant
const { accessToken } = await getAccessToken(req, res, {
scopes: ['read:trips'],
})
const response = await fetch(`${apiURL}/trips`, {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
Accept: 'application/json',
Authorization: `Bearer ${accessToken}`,
},
})
const trips = await response.json()
res.status(200).json(trips)
})
// /pages/trips/index.tsx
const TripsPage = (props: InferGetServerSidePropsType<typeof getServerSideProps>) => {
if (!props.user) return <div>User error!</div>
return (
<div>
// components that use the fetched data
</div>
)
}
export const getServerSideProps = withPageAuthRequired({
async getServerSideProps() {
const { data } = await axios.get('/api/trips')
try {
return {
props: {
data: data,
},
}
} catch (e) {
return {
notFound: true,
}
}
},
})
export default TripsPage
However, when I try to go to the http://localhost:3000/trips page after logging in, I get a error:
GET http://localhost:3000/trips 500 (Internal Server Error)
Uncaught Error: connect ECONNREFUSED ::1:80
at <unknown> (Error: connect ECONNREFUSED ::1:80)
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1487:16)
It seems like the request doesn't even leave my NextJS application. Seems like the internal API call failed. However, if I directly go to http://localhost:3000/api/trips I do get a response with the JSON data and if I console.log the accessToken it is valid. So authentication is working, but the issue is in the actual page which calls the NextJS proxy API, which calls my ExpressJS API.
The full error log on the NextJS console is:
error - AxiosError: connect ECONNREFUSED ::1:80
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1487:16) {
port: 80,
address: '::1',
syscall: 'connect',
code: 'ECONNREFUSED',
errno: -4078,
config: {
transitional: {
silentJSONParsing: true,
forcedJSONParsing: true,
clarifyTimeoutError: false
},
adapter: [Function: httpAdapter],
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
maxBodyLength: -1,
env: { FormData: [Function] },
validateStatus: [Function: validateStatus],
headers: {
Accept: 'application/json, text/plain, */*',
'User-Agent': 'axios/0.27.2'
},
method: 'get',
url: '/api/trips',
data: undefined
},
request: <ref *1> Writable {
_writableState: WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
destroyed: false,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: true,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
afterWriteTickInfo: null,
buffered: [],
bufferedIndex: 0,
allBuffers: true,
allNoop: true,
pendingcb: 0,
constructed: true,
prefinished: false,
errorEmitted: false,
emitClose: true,
autoDestroy: true,
errored: null,
closed: false,
closeEmitted: false,
[Symbol(kOnFinished)]: []
},
_events: [Object: null prototype] {
response: [Function: handleResponse],
error: [Function: handleRequestError],
socket: [Function: handleRequestSocket]
},
_eventsCount: 3,
_maxListeners: undefined,
_options: {
maxRedirects: 21,
maxBodyLength: 10485760,
protocol: 'http:',
path: '/api/trips',
method: 'GET',
headers: [Object],
agent: undefined,
agents: [Object],
auth: undefined,
hostname: null,
port: null,
nativeProtocols: [Object],
pathname: '/api/trips'
},
_ended: true,
_ending: true,
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 0,
_requestBodyBuffers: [],
_onNativeResponse: [Function (anonymous)],
_currentRequest: ClientRequest {
_events: [Object: null prototype],
_eventsCount: 7,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
destroyed: true,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
maxRequestsOnConnectionReached: false,
_defaultKeepAlive: true,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
strictContentLength: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
_closed: true,
socket: [Socket],
_header: 'GET /api/trips HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'User-Agent: axios/0.27.2\r\n' +
'Host: localhost\r\n' +
'Connection: close\r\n' +
'\r\n',
_keepAliveTimeout: 0,
_onPendingData: [Function: nop],
agent: [Agent],
socketPath: undefined,
method: 'GET',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
path: '/api/trips',
_ended: false,
res: null,
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: 'localhost',
protocol: 'http:',
_redirectable: [Circular *1],
[Symbol(kCapture)]: false,
[Symbol(kBytesWritten)]: 0,
[Symbol(kEndCalled)]: true,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype],
[Symbol(errored)]: null,
[Symbol(kUniqueHeaders)]: null
},
_currentUrl: 'http:/api/trips',
[Symbol(kCapture)]: false
},
page: '/trips'
}
Any idea what's going on here?
Try using 127.0.0.1 instead of localhost. I had the same issue.
The issue was that we not allowed to call an internal NextJS /api/ route in getServerSideProps. We need to call the external API directly, and not through the internal /api proxy.
More information: https://github.com/auth0/nextjs-auth0/issues/995
I have a website I am helping to maintain (but did not build myself), using Nuxt.js and Axios. It is currently showing an odd server behavior on the Home page. If I directly visit the home page (say: https://example.org):
Browser: Server error (500)
Server: Certificate has expired (for the twitter feed data call)
This error also happens when I am on example.org/about (which works) and hit a link formed like: Home
However, if I visit the home page (both show link as https://example.org) via a link on say example.org/about which is formed like: <span>Home</span>:
Browser: Page works!
Server: No errors
So, oddly enough, even for two different links for '/' one leads to the error but the other does not (and they both display the same thing in the URL bar). If I open the link directly at example.org:5000/tweets then it works fine (footnote: not sure why the design choice was made to use a different port there, possibly related). Has anyone seen this kind of behavior and know why that might happen? It persists on safe mode and on all major browsers. No changes were made with the code from when it worked to when it stopped working in the last couple of days. The specific error that I receive is shown like the below.
{ Error: certificate has expired
at TLSSocket.<anonymous> (_tls_wrap.js:1105:38)
at emitNone (events.js:106:13)
at TLSSocket.emit (events.js:208:7)
at TLSSocket._finishInit (_tls_wrap.js:639:8)
at TLSWrap.ssl.onhandshakedone (_tls_wrap.js:469:38)
code: 'CERT_HAS_EXPIRED',
config:
{ adapter: [Function: httpAdapter],
transformRequest: { '0': [Function: transformRequest] },
transformResponse: { '0': [Function: transformResponse] },
timeout: 0,
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
headers:
{ Accept: 'application/json, text/plain, */*',
'User-Agent': 'axios/0.16.2' },
baseURL: 'https://example.org:5000/',
method: 'get',
url: 'https://example.org:5000/tweets',
data: undefined },
request:
Writable {
_writableState:
WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
destroyed: false,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: true,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 0,
prefinished: false,
errorEmitted: false,
bufferedRequestCount: 0,
corkedRequestsFree: [Object] },
writable: true,
domain: null,
_events:
{ response: [Function: handleResponse],
error: [Function: handleRequestError] },
_eventsCount: 2,
_maxListeners: undefined,
_options:
{ protocol: 'https:',
maxRedirects: 21,
maxBodyLength: 10485760,
hostname: 'example.org',
port: '5000',
path: '/tweets',
method: 'get',
headers: [Object],
agent: undefined,
auth: undefined,
nativeProtocols: [Object],
pathname: '/tweets' },
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 0,
_requestBodyBuffers: [],
_onNativeResponse: [Function],
_currentRequest:
ClientRequest {
domain: null,
_events: [Object],
_eventsCount: 6,
_maxListeners: undefined,
output: [],
outputEncodings: [],
outputCallbacks: [],
outputSize: 0,
writable: true,
_last: true,
upgrading: false,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: [Object],
connection: [Object],
_header: 'GET /tweets HTTP/1.1\r\nAccept: application/json, text/plain, */*\r\nUser-Agent: axios/0.16.2\r\nHost: example.org:5000\r\nConnection: close\r\n\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: [Object],
socketPath: undefined,
timeout: undefined,
method: 'GET',
path: '/tweets',
_ended: false,
res: null,
aborted: undefined,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
_redirectable: [Circular],
[Symbol(outHeadersKey)]: [Object] },
_currentUrl: 'https://example.org:5000/tweets' },
response: undefined,
statusCode: 500,
name: 'NuxtServerError' }
Upgrading to the latest version of Node resolved this issue for me. I was experiencing an identical issue to what you described on Node v8.10.0. I upgraded to Node v14.18.1 and restarted Nuxt, and now the site works normally.
sudo npm cache clean -f
sudo npm install -g n
sudo n stable
I am getting back a response in node to fetch a PDF that I would like to save the binary data and upload it to S3 which I can then pull as I please for historical purposes. Right now I am having problems trying to extract that PDF raw data/binary data so that I can save that as a PDF and upload it, I think I am getting closer. this is the response.body that I am getting.
PassThrough {
_readableState: ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: BufferList { head: null, tail: null, length: 0 },
length: 0,
pipes: null,
pipesCount: 0,
flowing: null,
ended: false,
endEmitted: false,
reading: false,
sync: false,
needReadable: false,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
emitClose: true,
autoDestroy: false,
destroyed: false,
defaultEncoding: 'utf8',
awaitDrainWriters: null,
multiAwaitDrain: false,
readingMore: false,
decoder: null,
encoding: null,
[Symbol(kPaused)]: null
},
readable: true,
_events: [Object: null prototype] {
prefinish: [Function: prefinish],
unpipe: [Function: onunpipe],
error: [ [Function: onerror], [Function] ],
close: [Function: bound onceWrapper] { listener: [Function: onclose] },
finish: [Function: bound onceWrapper] { listener: [Function: onfinish] }
},
_eventsCount: 5,
_maxListeners: undefined,
_writableState: WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
destroyed: false,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: true,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
afterWriteTickInfo: null,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 0,
prefinished: false,
errorEmitted: false,
emitClose: true,
autoDestroy: false,
bufferedRequestCount: 0,
corkedRequestsFree: {
next: null,
entry: null,
finish: [Function: bound onCorkedFinish]
}
},
writable: true,
allowHalfOpen: true,
_transformState: {
afterTransform: [Function: bound afterTransform],
needTransform: false,
transforming: false,
writecb: null,
writechunk: null,
writeencoding: null
},
[Symbol(kCapture)]: false
}
This is my code:
platform.on(platform.events.loginSuccess, async function(e) {
let resp = await platform.get('/restapi/v1.0/account/~/extension/'+accountId+'/message-store', {
messageType: ['Fax'],
dateFrom: ['2021-05-01'],
dateTo: ['2021-05-16']
})
let jsonObj = await resp.json()
let attachId = jsonObj.records[0].id
let getMessageContent = await platform.get('/restapi/v1.0/account/~/extension/'+accountId+'/message-store/'+attachId+'/content/'+attachId, {
contentDisposition: ['Inline']
})
I know the response I am getting is correct because if I run that URL in postman and use the preview option, I can see the pdf (see screenshot). What am I missing?
That looks about right to me. The response.body is a readable node.js stream containing the binary data, and my guess is that Postman reads this stream automatically and displays the result.
The good news is that this type of stream is exactly what S3 wants as a request body when uploading files, which means that you do not need to save it anywhere - you can just pass it through directly to S3. Depending on your implementation, your code could look something like this:
const result = await s3Client.upload({
Bucket: 'MY_S3_BUCKET',
Key: 'myfilename.pdf',
Body: response.body,
}).promise();
Where response.body is the stream you have logged above. This should put the pdf file right up in S3 ready for downloading.
But if you do insist on saving the file, you can also pass the stream to the fs.writeFileSync method like so:
fs.writeFileSync('my-pdf.pdf', response.body);
**I tried passing in a parameter to my route and then passing that parameter to the variable axios with the url. The request succeeds if I remove the params object and instead hardcode the parameter in the url.
I am trying to post the question, but my word is little and the code is too much. I don't know how I can solve this so the explanation is enough to solve the question. I have explained it to the best of my ability. the code can tell much for itself. Thank you.
const axios = require("axios");
dotenv.config();
const Url = "https://api.dhl.com/location-finder/v1/find-by-address";
exports.getLocation = (req, res, next) => {
const country = req.body.countryCode;
axios
.get(Url, {
params: {
countryCode: country}
,headers: {'DHL-API-Key': process.env.LOCATOR_API_KEY}})
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
};```
//CODE CONSOLE LOG
**THIS IS THE CONSOLE LOG THE PARAMETER PART IS UNDEFINED HOW WILL I ADD THE PARAMETER
Error: Request failed with status code 400
at createError (/media/ALWI/HACKERFOREVER/MyProjects/JULEYBIB_SHIPPING/server/node_modules/axios/lib/core/createError.js:16:15)
at settle (/media/ALWI/HACKERFOREVER/MyProjects/JULEYBIB_SHIPPING/server/node_modules/axios/lib/core/settle.js:17:12)
at IncomingMessage.handleStreamEnd (/media/ALWI/HACKERFOREVER/MyProjects/JULEYBIB_SHIPPING/server/node_modules/axios/lib/adapters/http.js:236:11)
at IncomingMessage.emit (events.js:322:22)
at endReadableNT (_stream_readable.js:1187:12)
at processTicksAndRejections (internal/process/task_queues.js:84:21) {
config: {
url: 'https://api.dhl.com/location-finder/v1/find-by-address',
method: 'get',
params: { countryCode: undefined },
headers: {
Accept: 'application/json, text/plain, */*',
'DHL-API-Key': '**********************',
'User-Agent': 'axios/0.19.2'
},
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
adapter: [Function: httpAdapter],
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
data: undefined
},
request: ClientRequest {
_events: [Object: null prototype] {
socket: [Function],
abort: [Function],
aborted: [Function],
error: [Function],
timeout: [Function],
prefinish: [Function: requestOnPrefinish]
},
_eventsCount: 6,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
_SNICallback: null,
servername: 'api.dhl.com',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 9,
connecting: false,
_hadError: false,
_parent: null,
_host: 'api.dhl.com',
_readableState: [ReadableState],
readable: true,
_maxListeners: undefined,
_writableState: [WritableState],
writable: false,
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [Circular],
[Symbol(res)]: [TLSWrap],
[Symbol(asyncId)]: 301,
[Symbol(kHandle)]: [TLSWrap],
[Symbol(kSetNoDelay)]: false,
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kCapture)]: false,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0,
[Symbol(connect-options)]: [Object]
},
connection: TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
_SNICallback: null,
servername: 'api.dhl.com',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 9,
connecting: false,
_hadError: false,
_parent: null,
_host: 'api.dhl.com',
_readableState: [ReadableState],
readable: true,
_maxListeners: undefined,
_writableState: [WritableState],
writable: false,
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [Circular],
[Symbol(res)]: [TLSWrap],
[Symbol(asyncId)]: 301,
[Symbol(kHandle)]: [TLSWrap],
[Symbol(kSetNoDelay)]: false,
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kCapture)]: false,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0,
[Symbol(connect-options)]: [Object]
},
_header: 'GET /location-finder/v1/find-by-address HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'DHL-API-Key: *********************\r\n' +
'User-Agent: axios/0.19.2\r\n' +
'Host: api.dhl.com\r\n' +
'Connection: close\r\n' +
'\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: Agent {
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: [Object],
requests: {},
sockets: [Object],
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
maxCachedSessions: 100,
_sessionCache: [Object],
[Symbol(kCapture)]: false
},
socketPath: undefined,
method: 'GET',
insecureHTTPParser: undefined,
path: '/location-finder/v1/find-by-address',
_ended: true,
res: IncomingMessage {
_readableState: [ReadableState],
readable: false,
_events: [Object: null prototype],
_eventsCount: 3,
_maxListeners: undefined,
socket: [TLSSocket],
connection: [TLSSocket],
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
headers: [Object],
rawHeaders: [Array],
trailers: {},
rawTrailers: [],
aborted: false,
upgrade: false,
url: '',
method: null,
statusCode: 400,
statusMessage: 'Bad Request',
client: [TLSSocket],
_consuming: false,
_dumped: false,
req: [Circular],
responseUrl: 'https://api.dhl.com/location-finder/v1/find-by-address',
redirects: [],
[Symbol(kCapture)]: false
},
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
_redirectable: Writable {
_writableState: [WritableState],
writable: true,
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
_options: [Object],
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 0,
_requestBodyBuffers: [],
_onNativeResponse: [Function],
_currentRequest: [Circular],
_currentUrl: 'https://api.dhl.com/location-finder/v1/find-by-address',
[Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype] {
accept: [Array],
'dhl-api-key': [Array],
'user-agent': [Array],
host: [Array]
}
},
response: {**I tried passing in a parameter to my route and then pass the parameter to a variable the the variable to axios with the uri the requests succeeds if i remove the params object and if i hardcode the parameter in the url help me solve the parameter problem i am abit new
**I tried passing in a parameter to my route and then pass the parameter to a variable the the variable to axios with the uri the requests succeeds if i remove the params object and if i hardcode the parameter in the url help me solve the parameter problem i am abit new
**I tried passing in a parameter to my route and then pass the parameter to a variable the the variable to axios with the uri the requests succeeds if i remove the params object and if i hardcode the parameter in the url help me solve the parameter problem i am abit new
**I tried passing in a parameter to my route and then pass the parameter to a variable the the variable to axios with the uri the requests succeeds if i remove the params object and if i hardcode the parameter in the url help me solve the parameter problem i am abit new
**I tried passing in a parameter to my route and then pass the parameter to a variable the the variable to axios with the uri the requests succeeds if i remove the params object and if i hardcode the parameter in the url help me solve the parameter problem i am abit new
**I tried passing in a parameter to my route and then pass the parameter to a variable the the variable to axios with the uri the requests succeeds if i remove the params object and if i hardcode the parameter in the url help me solve the parameter problem i am abit new
status: 400,
statusText: 'Bad Request',
headers: {
date: 'Mon, 04 May 2020 09:02:52 GMT',
'content-type': 'application/json',
'content-length': '71',
connection: 'close',
'access-control-allow-origin': '*',
'access-control-allow-headers': 'origin,x-requested-with,accept,accept-encoding,content-type,dhl-api-key',
'access-control-max-age': '3628800',
'access-control-allow-methods': 'GET,OPTIONS',
'correlation-id': 'f10a4f9b-0538-4dd5-bdc0-9069f90558ad'
},
config: {
url: 'https://api.dhl.com/location-finder/v1/find-by-address',
method: 'get',
params: [Object],
headers: [Object],
transformRequest: [Array],
transformResponse: [Array],
timeout: 0,
adapter: [Function: httpAdapter],
xsrfCookieName: 'XSRF-**I tried passing in a parameter to my route and then pass the parameter to a variable the the variable to axios with the uri the requests succeeds if i remove the params object and if i hardcode the parameter in the url help me solve the parameter problem i am abit newTOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
data: undefined
},
**I tried passing in a parameter to my route and then pass the parameter to a variable the the variable to axios with the uri the requests succeeds if i remove the params object and if i hardcode the parameter in the url help me solve the parameter problem i am abit new
request: ClientRequest {
_events: [Object: null prototype],
_eventsCount: 6,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: [TLSSocket],
connection: [TLSSocket],
_header: 'GET /location-finder/v1/find-by-address HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'DHL-API-Key: ****************************\r\n' +
'User-Agent: axios/0.19.2\r\n' +
'Host: api.dhl.com\r\n' +
'Connection: close\r\n' +
'\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: [Agent],
socketPath: undefined,
method: 'GET',
insecureHTTPParser: undefined,
path: '/location-finder/v1/find-by-address',
_ended: true,
res: [IncomingMessage],
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
_redirectable: [Writable],
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype]
},
data: { error: [Object] }
},
isAxiosError: true,
toJSON: [Function]
}
It is a breaking change from axios version 0.19.
If you would like to add a parameter to a request you have to pass it via an interceptor.
As example:
const axios = require('axios');
// api openexchange
const oexchange = axios.create({
baseURL: 'https://openexchangerates.org/api/',
timeout: parseInt(process.env.TIMEOUTEXTERNALREQUEST)
})
oexchange.interceptors.request.use((config) => {
config.params = config.params || {};
config.params.app_id = process.env.OPENEXCHANGEAPITOKEN // <-- here add the query params in your case it will be countryCode
return config;
});
exports.cotacao = async (req, res) => {
try {
req.oexchange = await oexchange.get('latest.json') //here i'm calling external api with query params added in interceptor
return res.status(200).json(req.oexchange.data)
} catch (e) {
res.status(500).json({errors: [{ location: 'cotacao', msg: 'Houve um erro ao acessar a api do open exchange.', param: 'openexchangerates' }]})
}
}
It is a know behavior that was added in version 0.19 (May 30, 2019)
Currently there is a community effort to fix that behavior you can follow here, it is addressed to be fixed in release 0.20.
If you would like the old way of passing in url params you should use version 0.18 backwards.
Every code here is based in axios documentation
Following the Axios NuxtJS config, I created a proxy config like this on my nuxt.config.js:
proxy: {
'/api/': {
target: 'https://myapidomain.com/',
pathRewrite: { '^/api/': '' },
changeOrigin: true
}
}
This config works perfectly on dev environment, both server side rendering and client side rendering. Here is the code we use to create an api wrapper api.js:
export default (context, inject) => {
inject('api', {
getPageForSlug: (slugRoute) => {
return context.$axios.$get(`/api/pageForSlug?routeName=${slugRoute}`)
},
})
}
and then from any vue class:
const response = await app.$api.getPageForSlug(params.slug_route)
the only problem occurs when this code is called from the zeit now deployment. The client side works perfectly, but the server side returns this error:
START RequestId: dd92dbad-135f-414b-bc1d-df9faffaa681 Version: $LATEST
2019-08-30T17:46:03.098Z dd92dbad-135f-414b-bc1d-df9faffaa681 INFO λ Cold start took: 5265.617811ms
END RequestId: dd92dbad-135f-414b-bc1d-df9faffaa681
REPORT RequestId: dd92dbad-135f-414b-bc1d-df9faffaa681 Duration: 438.53 ms Billed Duration: 500 ms Memory Size: 3008 MB Max Memory Used: 92 MB
N',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
data: undefined },
request:
Writable {
_writableState:
WritableState {
objectMode: false,
highWaterMark: 16384,
finalCalled: false,
needDrain: false,
ending: false,
ended: false,
finished: false,
destroyed: false,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: true,
bufferProcessing: false,
onwrite: [Function: bound onwrite],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 0,
prefinished: false,
errorEmitted: false,
emitClose: true,
autoDestroy: false,
bufferedRequestCount: 0,
corkedRequestsFree: [Object] },
writable: true,
domain: null,
_events:
[Object: null prototype] { response: [Function], error: [Function] },
_eventsCount: 2,
_maxListeners: undefined,
_options:
{ protocol: 'http:',
maxRedirects: 21,
maxBodyLength: 10485760,
path: '/api/pageForSlug?routeName=lud_form',
method: 'GET',
headers: [Object],
agent: undefined,
auth: undefined,
hostname: 'localhost',
port: '3000',
nativeProtocols: [Object],
pathname: '/api/pageForSlug',
search: '?routeName=lud_form' },
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 0,
_requestBodyBuffers: [],
_onNativeResponse: [Function],
_currentRequest:
ClientRequest {
domain: null,
_events: [Object],
_eventsCount: 6,
_maxListeners: undefined,
output: [],
outputEncodings: [],
outputCallbacks: [],
outputSize: 0,
writable: true,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: [Socket],
connection: [Socket],
_header:
'GET /api/pageForSlug?routeName=lud_form HTTP/1.1\r\nAccept: application/json, text/plain, */*\r\nx-now-deployment-url: lps-5fxmi58fz.now.sh\r\nx-now-trace: staging-gru1\r\nx-real-ip: 177.45.65.235\r\nx-zeit-co-forwarded-for: 177.45.65.235\r\nupgrade-insecure-requests: 1\r\nx-forwarded-proto: https\r\nx-now-id: 7xllz-1567187175018-d0ce35475a9e\r\naccept-encoding: gzip, deflate\r\nuser-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36\r\nx-forwarded-for: 177.45.65.235\r\nx-forwarded-host: lps-danicuki.playax.now.sh\r\ndnt: 1\r\naccept-language: en-US,en;q=0.9\r\nconnection: close\r\nHost: localhost:3000\r\n\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: [Agent],
socketPath: undefined,
timeout: undefined,
method: 'GET',
path: '/api/pageForSlug?routeName=lud_form',
_ended: false,
res: null,
aborted: undefined,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
_redirectable: [Circular],
[Symbol(isCorked)]: false,
[Symbol(outHeadersKey)]: [Object] },
_currentUrl: 'http://localhost:3000/api/pageForSlug?routeName=lud_form' },
response: undefined,
isAxiosError: true,
toJSON: [Function] }
END RequestId: 6e355938-32d5-459a-adf7-08fb97101e29
REPORT RequestId: 6e355938-32d5-459a-adf7-08fb97101e29 Duration: 281.53 ms Billed Duration: 300 ms Memory Size: 3008 MB Max Memory Used: 117 MB
RequestId: 6e355938-32d5-459a-adf7-08fb97101e29 Error: Runtime exited with error: exit status 1
Runtime.ExitError
How to make the server side API request work on all environments?
This can be achieved using a rewrite in your now.json Vercel file. No need for a hack.
{
"version": 2,
"builds": [
{
"src": "nuxt.config.js",
"use": "#nuxtjs/vercel-builder",
"config": {}
}
],
"rewrites": [
{
"source": "/api/:match*",
"destination": "https://myapidomain.com/:match*"
}
]
}
Are you ready for the ultimate hack?
This is actually a common issue. When calling zeit now, a server doesn't actually get propped up. As such, you'll need to do it yourself.
The only time I've encountered a need to do this, I used express to solve it. A quick and dirty solution is to create another script (proxy.js), and have something like so:
import express from 'express'
import proxy from 'express-http-proxy'
const app = express()
app.use('/', proxy(`https://myapidomain.com`))
export default app
This does nothing but set up a reverse proxy to your API.
From there, in your zeit config, find your builds key if you have one, and replace it with this:
"builds": [
{ "use": "#now/next", "src": "package.json" },
{ "use": "#now/node", "src": "proxy.js" }
]
This will prop up and execute proxy.js when you build using zeit now.
Do note that this does mean you'll need to get the host in proxy.js to match the "normal" host. If you know the format of your config file (which you should), it may be possible to import and parse that in order to have one source of truth.
Let me know if this worked.