json.decode() 输入意外结束(在字符 1 处)
Posted
技术标签:
【中文标题】json.decode() 输入意外结束(在字符 1 处)【英文标题】:json.decode() Unexpected end of input (at character 1) 【发布时间】:2019-06-25 06:31:07 【问题描述】:我在登录用户时遇到了 Flutter 中的匿名关闭错误。它在几天前工作,但现在它不工作,我不知道为什么。所以请提前帮助和感谢..每当我填写详细信息并点击登录按钮时,它都会引发以下错误---
E/flutter ( 2914): [ERROR:flutter/shell/common/shell.cc(184)] Dart Error: Unhandled exception:
E/flutter ( 2914): FormatException: Unexpected end of input (at character 1)
E/flutter ( 2914):
E/flutter ( 2914): ^
E/flutter ( 2914):
E/flutter ( 2914): #0 _ChunkedJsonParser.fail (dart:convert/runtime/libconvert_patch.dart:1358:5)
E/flutter ( 2914): #1 _ChunkedJsonParser.close (dart:convert/runtime/libconvert_patch.dart:511:7)
E/flutter ( 2914): #2 _parseJson (dart:convert/runtime/libconvert_patch.dart:30:10)
E/flutter ( 2914): #3 JsonDecoder.convert (dart:convert/json.dart:540:36)
E/flutter ( 2914): #4 JsonCodec.decode (dart:convert/json.dart:167:41)
E/flutter ( 2914): #5 _SignInState._login.<anonymous closure> (package:restaurant_app/signin.dart:81:23)
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:restaurant_app/globalVar.dart';
import 'package:restaurant_app/homescreen.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:restaurant_app/signup.dart';
import 'package:http/http.dart' as http;
import 'package:flutter_html_view/html_parser.dart';
class SignIn extends StatefulWidget
@override
_SignInState createState() => _SignInState();
class _SignInState extends State<SignIn> with SingleTickerProviderStateMixin
TabController controller;
TextEditingController _email = new TextEditingController();
TextEditingController _password = new TextEditingController();
bool loading;
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>
();
@override
void initState()
// TODO: implement initState
super.initState();
controller = new TabController(length: 2, vsync: this);
loading = false;
_email = new TextEditingController(text: "rajeshvishnani");
_password = new TextEditingController(text: "Rajesh@MaaKiRasoi");
@override
void dispose()
// TODO: implement dispose
super.dispose();
controller.dispose();
setState(()
loading = false;
);
_email.dispose();
_password.dispose();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
bool _autoValidate = false;
Future _writer(String username, String password, String token) async
final storage = new FlutterSecureStorage();
await storage.write(key: authTokenKeys, value: token);
print(await storage.read(key: authTokenKeys));
await storage.write(key: nameKeys, value: username);
print(await storage.read(key: nameKeys));
await storage.write(key: passwordKeys, value: password);
static final String authTokenKeys = 'auth_token';
static final String nameKeys = 'username';
static final String passwordKeys = 'password';
_login(username, password) async
setState(()
loading = true;
);
var body = json.encode(
"username": username,
"password": password,
);
Map<String, String> headers =
'Content-type': 'application/json',
'Accept': 'application/json',
;
await http
.post("$GlobalVar.Ip/wp-json/jwt-auth/v1/token",
body: body, headers: headers)
.then((response)
var body = json.decode(response.body);
if (response.statusCode == 200)
// TODO: you need to store body['token'] to use in some authentication
loading = false;
_writer(_email.text, _password.text, body['token']);
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (BuildContext ctx) => HomePage()));
else
// TODO: alert message
final snackBar = SnackBar(
content: Text(body['message']),
);
_scaffoldKey.currentState.showSnackBar(snackBar);
setState(()
loading = false;
);
);
@override
Widget build(BuildContext context)
return Scaffold(
key: _scaffoldKey,
resizeToAvoidBottomPadding: false,
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('images/art.png'),
fit: BoxFit.fill,
colorFilter: ColorFilter.mode(
Colors.white12.withOpacity(0.2), BlendMode.dstATop),
),
),
child: ListView(
shrinkWrap: true,
physics: BouncingScrollPhysics(),
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).size.height / 30,
),
Align(
alignment: Alignment.topCenter,
child: CircleAvatar(
backgroundColor: Colors.grey,
radius: 55.0,
backgroundImage: AssetImage('images/logo.png'),
),
),
SizedBox(
height: MediaQuery.of(context).size.height / 30,
),
Stack(
alignment: Alignment.center,
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).size.height / 300,
child: new Center(
child: new Container(
height: 10.0,
color: Colors.black12,
),
),
),
Row(
children: <Widget>[
SizedBox(
width: MediaQuery.of(context).size.width / 4,
),
Chip(
label: Text(
"SIGN IN",
style: TextStyle(color: Colors.white, fontSize: 18.0),
),
backgroundColor: Color(0xFFD1A155),
),
SizedBox(
width: MediaQuery.of(context).size.width / 35,
child: Container(
width: MediaQuery.of(context).size.height / 12,
height: 2.0,
color: Colors.white,
),
),
Chip(
label: Text(
"SIGN UP",
style: TextStyle(color: Colors.white, fontSize: 18.0),
),
backgroundColor: Colors.black87,
),
],
)
],
),
SizedBox(
height: MediaQuery.of(context).size.height / 35,
),
Align(
alignment: Alignment.center,
child: Text(
"Welcome back!",
style: TextStyle(
fontSize: 20.0,
color: Color(0xFFD1A155),
),
)),
SizedBox(
height: MediaQuery.of(context).size.height / 30,
),
Form(
key: _formKey,
autovalidate: _autoValidate,
child: Column(
children: <Widget>[
Theme(
data: ThemeData(
hintColor: Colors.black26,
primaryColor: Color(0xFFD1A155),
),
child: Padding(
padding: const EdgeInsets.only(left: 15.0, right: 15.0),
child: TextFormField(
keyboardType: TextInputType.emailAddress,
//validator: _email.text.isEmpty?:null,
controller: _email,
decoration: InputDecoration(
border:
OutlineInputBorder(borderSide: BorderSide()),
prefixIcon: Icon(
Icons.email,
color: Color(0xFFD1A155),
),
hintText: 'Email Address',
hintStyle: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w400)),
),
),
),
SizedBox(
height: MediaQuery.of(context).size.height / 45,
),
Theme(
data: ThemeData(
primaryColor: Color(0xFFD1A155),
hintColor: Colors.black26),
child: Padding(
padding: const EdgeInsets.only(left: 15.0, right: 15.0),
child: TextFormField(
keyboardType: TextInputType.text,
obscureText: true,
controller: _password,
decoration: InputDecoration(
border:
OutlineInputBorder(borderSide: BorderSide()),
prefixIcon: Icon(
Icons.lock,
color: Color(0xFFD1A155),
),
hintText: 'Password',
hintStyle: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w400)),
),
),
),
Padding(
padding: const EdgeInsets.only(right: 15.0, left: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
children: <Widget>[
ActionChip(
onPressed: () ,
avatar: Checkbox(
value: false,
onChanged: (bool z)
print(z);
,
activeColor: Color(0xFFD1A155),
),
label: Text("Remember Me"),
backgroundColor: Colors.transparent,
),
],
),
Text(
"Forgot Password?",
style: TextStyle(
color: Color(0xFFD1A155),
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(left: 15.0, right: 15.0),
child: InkWell(
onTap: ()
_login(_email.text, _password.text);
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) => HomePage()));
,
child: loading
? CircularProgressIndicator()
: Container(
height: MediaQuery.of(context).size.height / 13,
//width: MediaQuery.of(context).size.height / 1.8,
decoration: BoxDecoration(
color: Color(0xFFD1A155),
borderRadius: BorderRadius.circular(5.0),
),
child: Center(
child: Text(
"LOGIN",
style: TextStyle(
color: Colors.white, fontSize: 18.0),
),
),
),
),
)
],
),
),
SizedBox(
height: MediaQuery.of(context).size.height / 15,
),
Stack(
alignment: Alignment.center,
children: <Widget>[
SizedBox(
height: 2.0,
child: new Center(
child: new Container(
height: 10.0,
color: Colors.black12,
),
),
),
Container(
height: MediaQuery.of(context).size.height / 18,
width: MediaQuery.of(context).size.height / 11,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(23.0),
color: Colors.white,
border: Border.all(color: Colors.black12)),
child: Center(
child: Text(
"OR",
style: TextStyle(fontSize: 18.0),
)),
),
],
),
SizedBox(
height: MediaQuery.of(context).size.height / 30,
),
Padding(
padding: const EdgeInsets.only(left: 15.0, right: 15.0),
child: Row(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.height / 13,
width: MediaQuery.of(context).size.width / 2.2,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: Colors.white,
border: Border.all(color: Colors.black12)),
child: Row(
children: <Widget>[
SizedBox(
width: 18.0,
),
Icon(Icons.tag_faces),
SizedBox(
width: 10.0,
),
Text(
"Facebook",
style: TextStyle(fontSize: 22.0, color: Colors.blue),
),
],
),
),
SizedBox(
width: MediaQuery.of(context).size.width / 40,
),
Container(
height: MediaQuery.of(context).size.height / 13,
width: MediaQuery.of(context).size.width / 2.3,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: Colors.white,
border: Border.all(color: Colors.black12)),
child: Row(
children: <Widget>[
SizedBox(
width: 18.0,
),
Icon(Icons.tag_faces),
SizedBox(
width: 10.0,
),
Text(
"Google+",
style: TextStyle(fontSize: 22.0, color: Colors.red),
),
],
),
),
],
),
),
SizedBox(
height: MediaQuery.of(context).size.height / 20,
),
Align(
alignment: Alignment.center,
child: InkWell(
onTap: () => Navigator.push(
context, MaterialPageRoute(builder: (context) => SignUp())),
child: RichText(
text: TextSpan(
text: "Don't have an account?",
style: TextStyle(fontSize: 20.0, color: Colors.black87),
children: <TextSpan>[
TextSpan(
text: ' Sign up',
style: TextStyle(
color: Color(0xFFD1A155),
fontWeight: FontWeight.bold)),
])),
),
),
SizedBox(
height: MediaQuery.of(context).size.height / 30,
),
],
),
),
);
【问题讨论】:
“匿名关闭”是错误中最不相关的部分。response.body
- 您传递给 json.decode(...)
的值不是有效的 JSON。第一个字符已经无效 - 可能只是 null
。
“匿名闭包”来自then(...)
,您在其中传递了一个调用json.decode()
的匿名闭包,并在异常输出中显示为第一个堆栈帧。因为传递的闭包(或函数)没有像 _login
这样的名称,所以它被列为“匿名闭包”。
弄清楚你从response.body
得到什么价值
“什么都没有”是什么意思?在var body = json.decode(response.body);
之前调用print('body: [$response.body]');
可能是空字符串""
【参考方案1】:
我也有类似的错误,请确保.decode
方法的参数不应该是空对象。而不是使用这一行:
var body = json.decode(response.body);
试试
if(response.body.isNotEmpty)
json.decode(response.body);
试试这个,希望对你有用。
【讨论】:
这对我的调试有帮助,我的问题在后端,响应错误,它在那里修复并且有效。【参考方案2】:打印您的身体并仔细检查您是否尝试解码数组而不是对象。
【讨论】:
这个!我第二次被这个抓住了。我有一个返回单个对象的查询,我将它视为一个数组。【参考方案3】:我遇到了类似的问题,我尝试了所有方法,但最终问题是我使用的是 http 而不是使用 https,即使 api 在 https 中,我忘记在 http 中添加 s。 从 http 更改为 https 后,错误消失了。
【讨论】:
以上是关于json.decode() 输入意外结束(在字符 1 处)的主要内容,如果未能解决你的问题,请参考以下文章
FormatException:输入意外结束(在字符 1 处)
I/flutter:FormatException:输入意外结束(在字符 1)
未处理的异常:FormatException:输入意外结束(在字符 1 处)