I'm building an app using MEAN stack. I'm using Proxy config file to make requests to the backend which is written in Node JS.
proxyconfig.json
{
"/api/*": {
"target": "https://localhost.com:3333",
"secure": false,
"changeOrigin": true,
"pathRewrite": {
"^/api": "https://localhost.com:3333/api"
}
}
}
Code in Component file
this.http.get("/api/posts",{responseType: 'text'})
.subscribe(
data =>
{
console.log('successs');
},
error =>
{
console.log(error);
}
);
Code in Node JS server
app.get('/api/posts', function(req, res) {
console.log('Posts Api Called');
res.status(200).send({ data: 'somedata' });
});
I'm getting 500 error when I inspect the request from Chrome. The GET method is not getting called at all. What could be the cause?
Finally, I made a silly mistake and this worked for me.
{
"/api": {
"target": "https://localhost:3333/api",
"secure": false,
"changeOrigin": true,
"pathRewrite": {"^/api" : ""}
}
}
Related
I have a Nuxt3 app that is using "server routes" to create backend APIs to use for the front-end.
I have the following server route:
server/api/imagekit/deleteFile.js:
import ImageKit from 'imagekit'
const imagekit = new ImageKit({
publicKey: useRuntimeConfig().public.imagekitPublicKey,
privateKey: useRuntimeConfig().imagekitPrivateKey,
urlEndpoint: useRuntimeConfig().public.imagekitBaseURL
})
export default defineEventHandler(async (event) => {
// Purge cache of file from Imagekit
// See detailed email from Rahul # imagekit dated aug 31, 2022
const body = await useBody(event)
const response = await imagekit.purgeCache(body.url)
return response
})
The above code works fine locally, but once I deploy to Firebase Hosting, I get the following server error when trying to access the API deleteFile:
description: ""
message: "Missing privateKey during ImageKit initialization"
statusCode: 500
statusMessage: "Internal Server Error"
url: "/api/imagekit/deleteFile"
In case it's relevant to this question, here is my code for Nuxt's nuxt.config.ts file where the runtimeConfig property is listed:
runtimeConfig: {
imagekitPrivateKey: '',
public: {
baseURL: process.env.NODE_ENV === 'production' ? 'https://example.com' : 'http://localhost:3000',
imagekitBaseURL: 'https://ik.imagekit.io/example/',
imagekitPublicKey: 'public_AdZM6u2+FvznG/LngYp7Ab3TJy4='
}
}
Also, my firebase.json uses 2 codebases for the functions: one for server and one for cloud functions:
{
"functions": [
{
"source": ".output/server",
"codebase": "nuxt"
},
{
"source": "functions",
"codebase": "functions"
}
],
"hosting": [
{
"site": "XXX",
"public": ".output/public",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"cleanUrls": true,
"rewrites": [
{
"source": "**",
"function": "server"
}
]
}
]
}
I do have an .env file in project root that holds the imagekitPrivateKey value.
How would I provide this information to Firebase hosting deployment so ImageKit properly initializes with the private key?
You can read the variables from .env in nuxt.config.ts as shown below:
export default defineNuxtConfig({
runtimeConfig: {
// Uppercase preferred in .env file
imagekitPrivateKey: process.env.IMAGEKIT_PRIVATE_KEY,
},
});
Then you can access it in your API routes:
export default defineEventHandler((event) => {
const { imagekitPrivateKey } = useRuntimeConfig();
return { message: "success" };
});
This might seem like a repeated question but i promise I've made sure
to check every related ones but non solve my problem
I am deploying a nextjs app on Firebase hosting using cloud functions,
the app does deploy and gives me back the hosting URL of app
link. visiting the URL i got this 403 forbidden error;
Your client does not have permission to get URL /nextServer/ from this server.
Which I fixed by adding allUsers and allAuthenticatedUsers as function invoker at function permission.
But then, after fixing that I got another error saying:
Error: could not handle the request
this terminated the function with a log of
Function execution took 804 ms, finished with status: 'crash'
This doesn't give any reason why the function crashed which has made fixing it all the more harder. Below is my nextServer function code:
const { https } = require("firebase-functions");
const { default: next } = require("next");
const isDev = process.env.NODE_ENV !== "production";
const server = next({
dev: isDev,
conf: { distDir: ".next" },
});
const nextjsHandle = server.getRequestHandler();
exports.nextServer = https.onRequest((req, res) => {
return server.prepare().then(() => {
return nextjsHandle(req, res);
});
});
and this is the firebase.json:
{
"hosting": {
"public": "public",
"site": "webavocat",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"function": "nextServer"
}
]
},
"functions": {
"source": ".",
"runtime": "nodejs16",
"ignore": [
"**/.vscode/**",
".firebase/**",
".firebaserc",
"firebase.json",
"**/node_modules/**",
"**/public/**",
"**/.next/cache/**"
]
}
}
The project folder structure is as shown below
Edit 1:
Don't really know if this is correct,
const nextjsHandle = server.getRequestHandler();
exports.nextServer = https.onRequest((req, res) => {
try {
return server.prepare().then(() => {
return nextjsHandle(req, res);
});
} catch (error) {
console.error(error);
}
});
but i used a try catch on the on the server function as #mdobrucki suggested. still no log on the why the function crashed though
LocalHost, Angular 11 (https://localhost:4200) and Node API (https://localhost:3001), both are using OpenSSL, browser is Chrome. To iron out Status: CORS error (due to diff ports) I follow this adding Proxy, got this in Angular's console
[HPM] Error occurred while trying to proxy request /somewhere1 from
localhost:4200 to https://localhost:3001 (DEPTH_ZERO_SELF_SIGNED_CERT)
(https://nodejs.org/api/errors.html#errors_common_system_errors)
Following didn't help:
Confirmed the Chrome brought up by F5 has chrome://flags/#allow-insecure-localhost Enabled.
Added process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; to Node API's server.js.
Proxy.conf.json
{
"context":
[
"/somewhere1",
"/xyz/somewhere"
],
"target" : "https://localhost:3001",
"secure": true,
"changeOrigin": true,
"rejectUnauthorzied": false,
"logLevel": "info"
}
angular.json
"serve": {
...
"options": {
"browserTarget": "myapp:build",
"ssl": true,
"proxyConfig": "src/proxy.conf.json"
Call API:
private http: HttpClient;
const httpOptions =
{
headers: new HttpHeaders({'Content-Type': 'application/json'}),
rejectUnauthorized: false
};
this.http.post<any[]>("/somewhere1/hello", {}, httpOptions).subscribe
Believe this is Angular end.
After days of frustration, I'm finally able to resolve them all and posting the solution here hope will help someone forward.
Environment:
Angular 11/12 front-end uses 3rd-party authentication such as Google.
API server is node 14.
Both are httpS/SSL.
Solution:
Follow this article to create trusted .crt and .key files
I didn't add localhost to hosts file.
Add a proxy.conf.js (or .json file with conformed format) and include it into angular.json file.
No need to specify httpOption for each individual http call.
API node, add the two files from 1 to server.js.
My Proxy.conf.js:
const PROXY_CONFIG =
[
{
context:
[
"/path1",
"/path2",
...
],
"target" : "https://localhost:3001", // I use 3000 for non-SSL
"changeOrigin": true, // helps on CORS Error in F12
"logLevel": "debug",
"rejectUnauthorzied": true, // or false if ok for you
"secure": false, // PROD must be "true", but DEV false else "UNABLE_TO_VERIFY_LEAF_SIGNATURE"
"strictSSL": true, // false is default
"withCredentials": true // required for Angular to send in cookie
}
]
module.exports = PROXY_CONFIG;
My Angular.json:
"architect": {
"serve": {
"builder": "#angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "myapp:build",
"ssl": true,
"proxyConfig": "src/proxy.conf.js"
...
My Server.js:
const fs = require("fs");
// following are the two files mentioned in No.5
const HttpSOptions =
{
key: fs.readFileSync('ssl\\server.key'),
cert: fs.readFileSync('ssl\\server.crt')
}
const httpSServer = httpS.createServer(HttpSOptions, app);
httpSServer.listen(3001, ()=>{console.log('httpS is on 3001');});
To verify certificates are FULLY trusted by Chrome, open one of your API URL call in Chrome, for example http://localhost:3001/path1/func/xyz, you should not see this
Here is an error text (app crashes at all 204 reponses):
[HPM] Error occurred while trying to proxy request /rest/profiles/change-password from site.loc:3005 to https://site.loc (ECONNRESET) (https://nodejs.org/api/errors.html#errors_common_system_errors)
Debugged backend response. It returns 204 status code with empty body (data = null). If I build an app everything is working fine. One more moment: it doesn't occur at other developer's MAC OS.
My webpack devServer config:
devServer: {
contentBase: PATHS.dist,
host: appDomain,
proxy: {
'/rest': {
target: appUrl,
secure: false,
changeOrigin: true
},
...
}
My enviroment:
Windows 10 Pro x64
node version: v12.18.4
webpack-dev-server: "^3.11.0",
Please, help!
I spent about 3 days on that error, myabe this answer could help anyone...
I didn't figure out why this error occur, good people helped me with this code:
proxy: {
'/rest': {
target: appUrl,
secure: false,
changeOrigin: true,
onProxyRes: function (proxyRes, req, res) {
console.log(proxyRes.statusCode);
},
onError: function (err, req, res) {
console.log(`req.body: ${req.body}`); // here it returned undefined
console.log(`err.code: ${err.code}`);
if (err.code === 'ECONNRESET') {
res.writeHead(204, {'Content-Type': 'application/json'});
res.end();
}
},
},
Previously tried to do this using webpack-dev-server bypass method, axios interceptors, but with no success.
I am trying to reverse proxy Angular using the proxy.conf.json to a lambda behind API gateway.
{
"/api/profile/*": {
"target": "http://asdasdfsdf.execute-api.ap-southeast-2.amazonaws.com",
"secure": false,
"logLevel": "debug",
"changeOrigin": false,
"headers": {
"host":"asdasdfsdf.execute-api.ap-southeast-2.amazonaws.com"
},
"pathRewrite": {
"^/api/profile": "/dev/profile"
}
},
}
I think there is an issue with the host header.
If I hit this now, I get unauthorized
However when I add the host header explicitly in postman, it works.
I used the bypass option.
To use it we have to change the proxy.conf.json to proxy.conf.js.
Check that all the references to proxy.conf.json now point to proxy.conf.js ( maybe you have it in angular.json , in options.proxyConfig or in the package.json).
After this we add the code to add the bypass option(in proxy.conf.js and it would end looking something like this:
const PROXY_CONFIG =
{
"/api/profile/*": {
target: "http://asdasdfsdf.execute-api.ap-southeast-2.amazonaws.com",
secure: false,
logLevel: "debug",
changeOrigin: false,
bypass: function (req, res, proxyOptions) {
req.headers["host"] = "asdasdfsdf.execute-api.ap-southeast-2.amazonaws.com";
},
pathRewrite: {
"^/api/profile": "/dev/profile"
}
},
};
module.exports = PROXY_CONFIG;
"target": "http://asdasdfsdf.execute-api.ap-southeast-2.amazonaws.com" was doing a redirect to https:// .... The proxy respected the redirect but it did not forward the headers in the config.
The solution was to use the https directly.