7

I am trying to fetch data from My site link: http://mrmatjar.com/kaka/dataaza.php

Here is my code

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:mrmatjar_afflite/shopobj.dart';
class Operations{
 static Future<List<ShopObj>> loly() async{
    List<ShopObj> ak= new List<ShopObj>();
      var res = await http.get(Uri.encodeFull("https://mrmatjar.com/kaka/dataaza"),headers: {"Accept":"application/json"});

    print(res);
    var v = json.decode(x.body);
    for(var h in v){
        ak.add(new ShopObj(h['title'], h['cost'], h['earn'], h['image']));
    }
    return ak;
  }
}

But it is not working. when I run it the Web app Breaks and when I use Break point it shows file call by blinding.dart

Y.A.D
  • 109
  • 1
  • 1
  • 5

2 Answers2

7

I have the same problem. It has to do with CORS. I added this to my server of the backend

sudo a2enmod headers

sudo nano /etc/apache2/mods-enabled/headers.conf

modify like this:

<IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "*"
</IfModule>

then restart apache2

sudo service apache2 restart
Muhammad Dyas Yaskur
  • 6,914
  • 10
  • 48
  • 73
Hairy Ass
  • 190
  • 2
  • 10
  • 2
    What if You do not have to privileges to make changes to the server? – ASAD HAMEED May 12 '21 at 09:26
  • @ASADHAMEED, I don't think there is an answer to this one. From what I understand about CORS, it's a security policy to ensure that no one can make a site that leeches off your server. So if the server doesn't allow you access, you can't get it. See the answers here: https://stackoverflow.com/questions/27365303/what-is-the-issue-cors-is-trying-to-solve – Levi Lesches Aug 04 '21 at 22:30
  • 1
    @LeviLesches I dug a little deeper into the issue and I found that it's an issue with the browser implementing "Same Origin Policy" and the server side has to use the following parameter `Access-Control-Allow-Origin: *` to allow all domains to access the server content or restrict it to some domains(Adding domain names instead of *). In my case, the server-side did not have this parameter set. – ASAD HAMEED Aug 08 '21 at 06:13
  • Right, which you cannot solve if you don't have control over the server. – Levi Lesches Aug 08 '21 at 06:54
6

Welcome to stack overflow :).

First:

I see some typo error in your code.

var v = json.decode(x.body); should be

var v = json.decode(res.body);

Second:

Once you fix the above you might face Cross Origin Request(CORS) error which may be because you have not set this up in your server. Especially if your flutter web application is not running in the same domain as the server where you api is running. Even if its on the same machine, you will have to allow the request from certain domain and ports. If you are not aware of CORS you can read here.

Third:

As I see you are processing the response without checking the statusCode of the response it would still lead to an error when you try to decode the response.

I have a simple running example here based on the DOGs public api.

import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;

class HttpRequestDemo extends StatefulWidget {
  @override
  _HttpRequestDemoState createState() => _HttpRequestDemoState();
}

class _HttpRequestDemoState extends State<HttpRequestDemo> {
  String imageUrl = "";

  @override
  Widget build(BuildContext context) {
    return Container(
        child: Column(
      children: <Widget>[
        Center(
          child: Image.network(
            imageUrl,
            height: MediaQuery.of(context).size.height / 3,
            width: MediaQuery.of(context).size.width / 3,
          ),
        ),
        FloatingActionButton(
          child: Icon(Icons.cloud_download),
          onPressed: () {
            fetchData();
          },
        )
      ],
    ));
  }

  fetchData() async {
    final res = await http.get("https://dog.ceo/api/breeds/image/random");

    if (res.statusCode == 200) {
      var v = json.decode(res.body);
      setState(() {
        imageUrl = v['message'];
      });
    }
  }
}

This app will show a new dog photo every time you press the floating action button as shown below which is based on the response from the api.

enter image description here enter image description here

Abhilash Chandran
  • 6,803
  • 3
  • 32
  • 50
  • 1
    thanks for helping. I added this 2 lines to server and its now working perfectly header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Credentials: true'); Thanks again :3 – Y.A.D Nov 13 '19 at 20:22
  • adding these headers to the server also not working – neha Jan 01 '20 at 06:26
  • Depending on the server you might need to add Allow-Methods as well including OPTIONS – Pjotr Gainullin Nov 30 '20 at 06:01