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.