What address should I use for "localhost" in my Flutter app? - node.js

I was using the following code within my Flutter app and it was working with no problems, but today after I upgraded my Flutter, it doesn't work and gives me XMLHttpRequest error.
Future<void> _authenticate(
String email, String password, String urlSegment) async {
final host = UniversalPlatform.isAndroid ? '10.0.2.2' : '127.0.0.1';
final url = Uri.parse('http://$host:8000/api/$urlSegment');
try {
final http.Response response = await http.post(
url,
headers: {"Content-Type": "application/json"},
body: json.encode(
{
'email': email,
'password': password,
},
),
);
Does anything have been changed in new Flutter version? Should I change the following line of code that specifies my host address?
final host = UniversalPlatform.isAndroid ? '10.0.2.2' : '127.0.0.1';
EDIT: I tried to add cors to my NodeJS backend server and this is my app.ts file as following:
import express, { Request, Response, NextFunction } from "express";
import cors from "cors";
import dotenv from "dotenv";
dotenv.config();
import config from "config";
import responseTime from "response-time";
import connect from "./utils/connect";
import logger from "./utils/logger";
import routes from "./routes";
import deserializeUser from "./middleware/deserializeUser";
import { restResponseTimeHistogram, startMetricsServer } from "./utils/metrics";
import swaggerDocs from "./utils/swagger";
const allowedOrigins = ['http://localhost:8000' , 'https://10.0.2.2:8000', 'http://127.0.0.1:8000'];
const options: cors.CorsOptions = {
origin: allowedOrigins
};
const port = config.get<number>("port");
const app = express();
app.use(express.json());
app.use(cors(options));
app.use(deserializeUser);
app.use(
responseTime((req: Request, res: Response, time: number) => {
if (req?.route?.path) {
restResponseTimeHistogram.observe(
{
method: req.method,
route: req.route.path,
status_code: res.statusCode,
},
time * 1000
);
}
})
);
app.listen(port, async () => {
logger.info(`App is running at http://localhost:${port}`);
await connect();
routes(app);
startMetricsServer();
swaggerDocs(app, port);
});
But still doesn't work and I get the same error!

You've set the allowed origins to :8000, but that's the backend server's address. Instead, you need to set it to the Flutter debug server's address (and eventually to the web server where you host the production app, if that's not exactly the same as the backend server). (You can remove all the addresses ending in 8000.)
The problem is that the debug server picks a random port for each run. You can tell it to use a fixed port and then that becomes the port you need to include in your allowed origins.
Add --web-hostname=localhost --web-port=9999 as command line parameters to where you run your main.dart, then add localhost:9999 as an allowed origin.
(As a get-out-of-jail, also try * as an allowed origin.)
Finally, you should probably explicitly set the CORS allowed methods to the list of methods your server's API expects; probably OPTIONS, GET and POST.

Related

why do i get a this cors error from using socket.io

I am using react and express js but when trying to get the socket io to connect to the client from the server I get a cors error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8080/socket.io/?EIO=4&transport=polling&t=O6YJzcv. (Reason: CORS header ‘Access-Control-Allow-Origin’ does not match ‘http://localhost:3000/’)
The code from the backend looks like this:
const express = require('express');
const { createServer } = require('http');
const { Server } = require('socket.io');
const cors = require('cors')
const app = express();
const httpServer = createServer(app);
const io = new Server(httpServer, {
cors: {
origin: 'http://localhost:3000/',
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true
}
});
app.use(cors())
io.on('connection', socket => {
console.log('connection to derver')
})
httpServer.listen(8080)
And the code from the client like this:
import { useState, useEffect } from 'react';
import axios from 'axios';
import { io } from "socket.io-client";
const socket = io("http://localhost:8080", {
withCredentials: true,
extraHeaders: {
"my-custom-header": "abcd"
}
});
function App() {
return (
<div className="App">
<form >
<label>dummy text</label>
</form>
</div>
);
}
export default App;
I dont know what is causing the error and I have been trying to debug it but only got so far. Tried finding other peoples code seing if that would work but copying havent solved it. I would preciate all the help i could get.
If you change the client socket.io initialization to only use a webSocket, then you won't have CORs issues because webSocket connections are not subject to CORs. But, by default, socket.io starts a connection with several regular http requests which are subject to CORs. So, you can tell socket.io to just start immediately with a webSocket connection by adding the transports option like this:
const socket = io("http://localhost:8080", {
withCredentials: true,
extraHeaders: {
"my-custom-header": "abcd"
},
transports: ["websocket"]
});
P.S. One cause of CORs issues in your code is your use of a custom header which is not explicitly enabled for CORs access and triggers CORs pre-flight authorization. But, if you configure it to just use the webSocket transport from the beginning, then you don't have to worry about any of that CORs stuff.

Nest JS CORS Error 0 Unknown With Android Browsers But Working With PC Broswers

I Use NestJs as a backend server and angular as a frontend
it's okay with me when I use chrome on pc and I can do all my requests
but when I use my android chrome with DevTools I receive this error
message: "Http failure response for http://localhost:3000/users/login: 0 Unknown Error"
here is a snapshot of the error message
enter image description here
it also send the same error with pc chrome if i didnt open CORS on NestJs
here Is My COSR Config
import { ValidationPipe } from '#nestjs/common';
import { NestFactory } from '#nestjs/core';
import { NextFunction, Request, Response } from 'express';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.use((req: Request, res: Response, next: NextFunction) => {
console.log(req);
next();
});
app.useGlobalPipes(new ValidationPipe());
app.enableCors({
origin: true,
methods: ['GET', 'PUT', 'POST', 'DELETE'],
exposedHeaders: ['x-auth'],
});
await app.listen(3000);
}
bootstrap();
by the way when I log the request on my nest app
I didn't receive any request
I think NestJsrefused it immediately
I found Where is the problem
I was using the localhost as a Backend IP and the application was connecting on my local pc Backend and that was the problem
I solved this by editing the Backend IP to the production IP
and finally, everything works good ,, Thanks All

getting CORS and network error while calling axios post request using Vue js

I am getting error while calling axios post request. But it works properly on postman.
The code I used for calling the request is
methods : {
displayData(){
var config = {
method: 'post',
url: 'http://localhost:5000/api/request/displayRequest',
headers: {
'Content-Type': 'application/json'
},
data : JSON.parse(JSON.stringify(this.user._id))
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
},
async mounted(){
this.displayData()
}
I have already implemented CORS on the back-end in server.js
// Cors Middleware
const cors = require('cors');
app.use(cors());
app.options("*", cors());
app.use(
cors({
origin: (origin, callback) => callback(null, true), // you can control it based on condition.
credentials: true, // if using cookie sessions.
})
);
in your backend use this :
npm i cors
and in your express backend entrypoint:
const cors = require("cors");
app.use(cors());
app.options("*", cors());
You are running your front-end on localhost and using some port. Also, your back-end is running on localhost, port 5000. But your front-end application can not access any other port due to CORS policy. You can solve this problem in the back-end if you are using Node JS.
Install cors by the following command:
npm i cors
Then on your server file, change your app by
app.use(cors());
N.B. If you used React js, you could use http-proxy-middleware. Just create a file inside the src directory named "setupProxy.js". and add the following lines.
const { createProxyMiddleware } = require("http-proxy-middleware");
module.exports = function (app) {
app.use(
"/api",
createProxyMiddleware({
target: "http://localhost:5000/",
})
);
};
Don't forget to change the port in this file into the port of your server.

How to set proxy when using axios to send requests?

I am using a package called 'concurrently' to run my client and server at the same time on localhost. Client runs on port 3000 while server runs on port 5000. I have set proxy in the package.json of server in the following manner:
"proxy": "https://localhost:5000"
But when I make a request from client in the following manner:
const config = {
headers: {
'Content-Type': 'application/json'
}
};
const res = await axios.post('/api/users', body, config);
It says: POST http://localhost:3000/api/users 404 (Not Found). I don't understand why but despite setting proxy, axios keeps making request to port 3000 instead of port 5000. What is the issue?
I just want to say that the solution of adding cors is not a solution. You need to include the proxy "proxy" : "https://localhost:5000" in the package.json, you may need to restart or something or other-- but if you choose to use cors instead, you are allowing anyone to access your API. That means your database is wide open for people to poke around with. Passwords, emails, users, etc. It's all compromised.
I got it working correctly. What I did was:
1) change axios.post('/api/users', body, config); to axios.post('http://localhost:5000/api/users', body, config);
2) Then in the 'users' express route on the server side, add CORS functionality by installing 'cors' npm package, and then adding the following lines:
const router = express.Router();
...
// add these lines
var cors = require('cors');
router.use(cors());
...
router.post('/', async (req, res) => {
...
});
as far as I understood your question, what you need is to refer Axios developer documents. for time being.
check this
import axios, { AxiosInstance } from 'axios';
import * as tunnel from 'tunnel';
const agent = tunnel.httpsOverHttp({
proxy: {
host: 'proxy.mycorp.com',
port: 8000,
},
});
const axiosClient: AxiosInstance = axios.create({
baseURL: 'https://some.api.com',
httpsAgent: agent,
});
In my case I didn't check well, it appeared that the call was actually forwarded to the api server at the proxy address.
Check that the server is running and whether it is receiving your calls or not.
when I send request to a server with proxy my code works successful. I hope this answer useful to you or another peoples.
const axios = require("axios");
const cheerio = require('cheerio');
async function sendRequestWithProxy() {
let proxyServer = {
"host" : "YOUR_PROXY_HOST",
"port" : "YOUR_PROXY_PORT",
"username" : "YOUR_PROXY_USERNAME",
"password" : "YOUR_PROXY_PASSWORD"
};
var ProductUrl = "http://YOUR_REQUEST_URL";
await axios.get(ProductUrl, {
proxy: {
host: proxyServer.host,
port: proxyServer.port,
auth: {username: proxyServer.username, password: proxyServer.password}
},
headers: {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36', }
}).then((response) => {
const $ = cheerio.load(response.data);
let productInfo = $("#HTML_ID_ATTRIBUTE").text();
///YOUR CODE
}).catch(function (error) {
if (error.response) {
//ERROR AREA
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
}
});
}

How to fix "Response to preflight request doesn't pass access control check: It does not have HTTP ok status" error in react app with nodejs api

I have been trying to do an api call (nodejs with express running on localhost) from a react app running in the browser over a local dev server (web-pack dev server). Everything was working well until I tried to call the api. They are both running on separate ports.
I have tried adding the cors headers (Recommended by MDN) to both the post call (from the app in browser) and to the response from the Nodejs API but neither of these solved the issue.
Code for the api call (in browser):
const headers = {
'Content-Type': 'application/json',
'access-token': '',
'Access-Control-Allow-Origin': '*',
}
export default async () => {
try {
const body = JSON.stringify({
test: true,
})
const response = await fetch('http://localhost:1337/internal/provider/check_email_exist', {
method: 'POST',
headers,
body,
})
console.log(response)
} catch (e) {
return e
}
}
API Middleware (in nodejs):
// Verify All Requests
app.use(VerifyToken)
// Compress
app.use(compression())
// Helmet middlware
app.use(helmet())
// Body Parser
app.use(bodyParser.urlencoded({
extended: false,
}))
app.use(bodyParser.json())
The expected result is to just give a 200 status code and respond with the data.
The actual output is:
OPTIONS http://localhost:1337/internal/provider/check_email_exist 404 (Not Found)
Access to fetch at 'http://localhost:1337/internal/provider/check_email_exist' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
Since you're using webpack-dev-server you can use the proxy option DevServerProxy.
Your configuration will look like this:
// webpack.config.js
devServer: {
proxy: {
'/internal': 'http://localhost:1337'
}
}
Since I can't see your express routes on your question I'm speculating about the proxy route if your API lives on /internal endpoint then you should modify your React code like this:
const response = await fetch('/internal/provider/check_email_exist', {
method: 'POST',
headers,
body,
})
As you can see I ommited the https://localhost:1337 because the proxy option from webpack-dev-server will handle this and it will redirect to http://localhost:1337. Hope this will help you. Cheers, sigfried.
EDIT
As the comment on your question pointed out you should set the headers on your express server, not the client, for this task you can use the cors-middleware package.
Maybe this can help if you face with preflight errors.
My full config:
const cors = require('cors');
const express = require('express');
const { createProxyMiddleware: proxy } = require('http-proxy-middleware');
...
const logLevel = 'info';
const ip = require('ip').address();
const proxyOptions = {
xfwd: true,
target,
changeOrigin: true,
logLevel,
cookieDomainRewrite: {
'*': 'localhost',
},
headers: {
'X-Forwarded-For': ip,
'X-Node': 'true',
},
};
const backNginxApp = express();
backNginxApp.use(
cors({
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
origin: 'http://localhost:3000',
optionsSuccessStatus: 200,
credentials: true,
})
);
backNginxApp.use('/api', proxy(proxyOptions));
API: const target = 'https://someapi.com'
Local development running at: http://localhost:3000

Resources