72

I m building a flutter app with django rest-framework. The registration api is working fine in Postman but after some successful registration from the flutter app it is showing the above error. The request is been sent on https address.

Removed csrf. Nothing happens.

Request:

var data = {'email':signupemailidcontroller.text,
            'password1':passwordcontroller.text,
            'password2':confirmpasswordcontroller.text,
           };
        //http request here
        await http.post(websitesignupurl,
                        headers: headers,
                        body: json.encode(data))
          .then((onResponse){
            print(onResponse.body);
          }).catchError((onerror){
            print(onerror.toString());
        });

Output in Console:

SocketException: OS Error: Connection refused, errno = 111

I Expect the response of this request to be a Json object containing the user and token.

Rohan Thacker
  • 4,054
  • 3
  • 15
  • 28
Harnish Rajput
  • 831
  • 1
  • 6
  • 9
  • 1
    Harnish if the answer I have given below helped you, do consider marking it as the accepted answer. So that we can help others who have the same question. – Rohan Thacker May 07 '20 at 19:53
  • 2
    is this being run on PythonAnywhere? if you have a free user account, then you will only be able to make http posts to endpoints on the PythonAnywhere whitelist https://www.pythonanywhere.com/whitelist/ – conrad Jun 22 '20 at 10:04

21 Answers21

144

Harnish, need a few more details in-order to debug this error.

  1. Are you running the server locally or communicating with a remote server?
  2. Are you running the app on the Android Emulator?

Possible Solution:

If you're running the server locally and using the Android emulator, then your server endpoint should be 10.0.2.2:8000 instead of localhost:8000 as AVD uses 10.0.2.2 as an alias to your host loopback interface (i.e) localhost

Note on Futures

I noticed above that the code is using await and then on the same line. This can be confusing, to be clear, await is used to suspend execution until a future completes, and then is a callback function to execute after a future completed. The same could be written as below

void myFunction() async {
    var data = {};
    var response = await http.post(URL, headers:headers, body:data);
    if (response.statusCode == 200) {
        print(reponse.body);
    } else {
       print('A network error occurred');
    }
}

or the non async/await method

void myFunction() {
    var data = {};
    http.post(URL, headers:headers, body:data)
    .then((response) => print(response.body))
    .catchError((error) => print(error));
}

For a more detailed information on Futures in Dart please read https://www.dartlang.org/tutorials/language/futures

Rohan Thacker
  • 4,054
  • 3
  • 15
  • 28
  • What should be the host link if I want to run the application on my physical phone? Also how would things work if I upload the application on google play store what would be the host link then? – chaitanya Harde Feb 07 '20 at 08:32
  • i am facing same issue with Remote server – Apar Amin Mar 09 '20 at 05:36
  • 1
    @chaitanyaHarde To run a server on your local machine and be able to access it on your physical device, you would need use the `adb reverse` command with the appropriate `tcp port` for your application as mentioned above. When the application is on the playstore, you would need to use a server configured on a publicly accessible IP address or domain – Rohan Thacker Apr 28 '20 at 18:48
  • You are a savior. Thanks @RohanThacker – Kennedy Owusu Apr 04 '22 at 21:08
  • Using http://10.0.2.2:8000/ as the base URL while connecting to a local server through an Android virtual device worked perfectly for me! Thanks! – Max May 02 '22 at 22:32
23

I went to the terminal and used ifconfig command

I got my IP address: 192.168.0.109

enter image description here

Then I simply replaced this IP address with my "localhost" in flutter app http requests. And it worked like a charm!

Dharman
  • 26,923
  • 21
  • 73
  • 125
spycbanda
  • 1,204
  • 6
  • 23
  • 3
    Inside terminal running ipconfig command gave me IPV4 address: `192.168.1.101` Then I simply replaced this IP address with my `127.0.0.1:8000` in flutter app `http` requests. And it worked like a charm! For `Laravel` : `php artisan serve --host 192.168.1.101 --port 80` – CodingEra Apr 20 '21 at 19:29
10

In addition to Rohan's answer you can also read:

Unable to make calls to Localhost using Flutter, random port being assigned to HTTP GET call

I was trying to run my app on physical device using local server so, for that i had to use the below mentioned command, here keep in mind change the port number according to your own port number

adb reverse tcp:3001 tcp:3001

As @maheshmnj pointed that this command is redirecting your phone's port 3001 to your computer's port 3001. In case if you want to redirect port 2000 of your phone to port 3000 of your computer then you could do this adb reverse tcp:2000 tcp:3000

you can also read about adb and networking via going through below mentioned page https://developer.android.com/studio/command-line/adb.html

taranjeet singh
  • 1,096
  • 11
  • 10
  • I was struggling for a long time. Thank you so much. Your solution worked out for me. – JOSEPH Blessingh Mar 16 '20 at 11:55
  • 1
    I would like to add to @taranjeetsingh's answer the command actually redirects your phone’s port 3001 to your computer’s port 3001. In Case you would like to redirect port 2000 of your phone to computers port 3000,Then the command would be ``` adb reverse tcp:2000 tcp:3000``` – Mahesh Jamdade May 21 '20 at 03:14
9
  • if in localhost instead localhost use the IP of your network
  • hint:for find Ip in cmd run ipconfig and get the ipv4

1: Example:

await http.post("http://127.68.34.23/wp-json/...",
                    headers: headers,
                    body: json.encode(data))

if in server write the url of main in url

spycbanda
  • 1,204
  • 6
  • 23
Rahman Rezaee
  • 1,326
  • 13
  • 22
  • Hi! I'm stuck looking for answers. My problem is that when I get a "response", the backend returns an HTML file, and i dont know why. Can you help me? – Mavro Jul 29 '20 at 02:29
  • I'm using xampp with mariadb, and as a backend I use php (aid with yii2 framework) – Mavro Jul 29 '20 at 02:30
  • You must check your server in most place return api if get data from html no problem – Rahman Rezaee Feb 01 '21 at 07:13
5

Try adding <uses-permission android:name="android.permission.INTERNET"/> to your manifest. This solved this issue for me.

Tatenda Zifudzi
  • 487
  • 5
  • 17
  • If you're having this problem on devices outside test environment this is the only solution – Toheeb May 19 '20 at 16:13
5

I had the same problem running in a real device, and only changing the IP in API link doesn´t work.

The solution for me was to put the server run with the command below:

manage.py runserver 0.0.0.0:8000

Then pass your machine IP to the API link instead of localhost, as the sample below:

http://192.168.0.67:8000
4

If you are using 'localhost' in your url, change it to your ipv4 address and it will work

4

This problem occurs when the endpoint are incorrect or your host and server backend (Example Laravel API)doesn't share the same IP address.

Solution is.

  1. Connect your workspace (computer, emulator, devices) in the same network.
  2. Find your IP by typing on terminal ifconfig.
  3. If you build your API with Laravel, start the server appointing to IP ADDRESS of your computer, sudo php artisan serve --host YOUR_COMPUTER_IP_ADDRESS --port NUMBER

Example:

`sudo php artisan serve --host 192.168.1.11 --port 80`
  1. Test your endpoint in Postman or similar Application and type http://192.168.1.11:80/Your_Route
  2. If everything is working good, you can run with app. Go!!!
3

In C#[.net core api], go to launchSettings.json under Properties tab and change the follwing code to this(change localhost to 0.0.0.0 on applicationURl) and on the app(flutter), use ur local IPV4 IP. ex: (192.169.0.10)

"coreWebAPI": {
      "commandName": "Project",
      "launchBrowser": false,
      "launchUrl": "api/values",
      "applicationUrl": "http://0.0.0.0:5000", 
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
Felipe Thomé
  • 323
  • 2
  • 9
2

This is what I had to change to fix the same error in my case:

  • Start django with python manage.py runserver 0:8000 and not just python manage.py runserver (0:8000 is the abbreviation for 0.0.0.0:8000 and makes your web application visible on your local network - see https://docs.djangoproject.com/en/3.0/ref/django-admin/#runserver)
  • In your flutter app specify the server address using your pc local ip, i.e. instead of http://localhost:8000 use something like http://192.168.1.2:8000. To retrieve your current ip address run ipconfig in the terminal if on Windows, otherwise ifconfig.
  • Update allowed host in django settings if necessary. For example set ALLOWED_HOSTS = ['*', ] (but only in your dev environment!)
Christopher Moore
  • 12,922
  • 9
  • 35
  • 46
Sergio Morstabilini
  • 2,005
  • 21
  • 28
2

Soltuion that worked on my machine

[√] Flutter (Channel stable, 2.5.3, on Microsoft Windows [Version 10.0.19043.1288], locale en-US)
[√] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
[√] Chrome - develop for the web
[√] Android Studio (version 2020.3)
[√] VS Code (version 1.61.2)
[√] Connected device (3 available)

STEP: 1 (get your ipv4)

in terminal/cmd type

  • ifconfig for Mac/Linux/Unix
  • ipconfig for Windows

you will get some result in windows it looks like enter image description here

STEP: 2 (change your request url)

❌ Dont do

  • http.get('localhost/my-local-rest-api/etc'
  • 127.0.0.1//my-local-rest-api/etc.

✅ Do

  • for android http.get('10.0.2.2/my-local-rest-api/etc
  • for ios http.get('192.168.8.155/my-local-rest-api/etc

IMPORTANT

always pass Uri instead of raw String example: http.get(Uri.parse('my-url-in-raw-string'))

STEP 3: enable un-encrypted networking connections

for Android

in android/app/src/debug/AndroidManifest.xml

<manifest ...other params...>
   // STEP: 1 make sure you have INTERNET permission
   <uses-permission android:name="android.permission.INTERNET" />

   <application
        android:label="YourAppName"
        android:usesCleartextTraffic="true"> <-- STEP: 2 add this line
        <activity
    </application>
</manifest>

for iOS

in ios/Runner/Info.plist add this

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsLocalNetworking</key>
    <true/>
</dict>
sultanmyrza
  • 3,093
  • 23
  • 19
1

I fixed this with $ adb tcpip <port-your-local-server>

1

What you need to do is to get your public PC IP and use it in your URL for example: http://192.168.0.67:3000, where 3000 is the port no.

1

I had the same issue in flutter with spring backend. Instead of using 'http://localhost:8080/' in my requests, I changed this to 'http://143.235.7.641:8080/' where '143.235.7.641' is my Wi-Fi IPv4 address, and it worked.

(NOTE : I assume you are testing flutter in physical phone,and phone and computer are connected the same wi-fi.)

  • Hi, I tried using ipv4 add of my wfi ,it still gives me the same error ``` Unhandled Exception: SocketException: OS Error: Connection refused, errno = 111, address = 127.0.0.1, port = 53182``` my backend is in flask-socektio. The flask-socketio never runs on localhost idk y. If I give host='localhost; it says this ``` wsgi starting up on http://[::1]:5000``. Can u tell me how to fix this? also how to connect to flutter ? –  May 24 '21 at 16:59
1

I know that the question is too old, But I will answer this because this may be helpful to someone who has this problem.

Without more details, I can't give a specific solution. But with following conditions can give a specific solution

  • I imagine that the API host was in local computer
  • I imagine that you use your emulator for running the app

The URL you tried with postman maybe something like this http://127.0.0.1:[port number]/register or http://localhost:[port number]/register. But this may not work with an emulator because it doesn't have access to that URL. To get access to the local host of your you need to find out the host address.

Follow these steps to get your host address.

  • Click on the three dots(More) in the android emulator
  • Setting -> Proxy
  • You can change your host address if you like by selecting `Manual proxy configuration

Then you can see your host name with the port number. Then replace your URL with those like http://10.0.0.2:5000/register.

enter image description here

0

I had this same issue once, After going through some overly complicated stackoverflow answers and google search, finally i figure it out, In this case you are most likely to be using a android emulator, So just turn on the mobile data on the emulator then try it again, i'm sure that this time it will work.

Abhilash TU
  • 301
  • 2
  • 5
0
final response = await client.post(
    "http://192.xxx.xx.xx/api/signin", 
    headers: {"Authorization": apiKey},
    body: jsonEncode({
      "username": username,
      "password": password,
    }));

Even I had got a SocketException Error but I replaced my IP address and didn't mention any Port number and it worked for me, and if I mention the port number it would throw an error. Hoping this would work out.

I am using Flask for backend ,using blocs.

0

For mac users to check ip address

in terminal type: ipconfig getifaddr en0 and use that Ip address as below

import 'dart:io';

import 'package:http/http.dart' as http;
import 'package:fluttertoast/fluttertoast.dart';

class AuthAction {
  static String BASE_URL = 'http://192.168.0.105:27017/';

  static Future<Null> signUpAction(
      firstName, lastName, email, password, userName) async {
    try {
      http.Response res = await http.post( Uri.parse(BASE_URL + 'signUp' ));
      print(res);

      if (res.statusCode == 200) {
      }
    } catch (err) {
      print(err);

        // Fluttertoast.showToast(msg: 'err');
    }
  }
}

Note: I did not touch the port on which my mongo-node server is running. Which is 27017

0

Try ths link delay the fuction and your will not get this error

Future.delayed(const Duration(milliseconds: 500), () {
    widget.callback();
  });

It Work for me

Urvish Jani
  • 98
  • 1
  • 3
0

If you are running on real phone, then you will get this error even if you add your localhost address to allowed host. For me, connecting my laptop to my phone's hotspot and running django server with laptop's ipv4 address (which you can find by using ipconfig command) by python manage.py runserver 192.168..:8000 i.e. your ipv4 address:port number, than you will be able to access django server using your phone's browser as well, now add this your ipv4 address to your allowed host. And, change your url from localhost or 127.0.0.1 to your ipv4 address. I hope this resolves your issue.

  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 17 '22 at 16:46
0

Replace your URL with:

Uri.parse("YourURL").replace(host: "YourIPAddress");

Explanation: This error means your host-address isn't correct (as already in above answers pointed out). As you probably have a physical device it must access the emulator server you hooked up to your computer (aka your IP adress).

How to get my IP-Adress?

MAC: ifconfig | grep "inet " | grep -Fv 127.0.0.1 | awk '{print $2}'

WINDOWS: netsh interface ip show address | findstr "IP Address"

Paul
  • 588
  • 6
  • 16