【问题标题】:Flutter can't connect to Rails API only properlyFlutter 无法正确连接到 Rails API
【发布时间】:2020-01-04 08:10:23
【问题描述】:

好的,伙计们,这是我的问题。

我有一个仅标准 Rails 5 API 设置。

我的用户控制器非常标准:

# frozen_string_literal: true

class UsersController < ApplicationController
  before_action :set_user, only: %i[show update destroy]

  # GET /users
  def index
    @users = User.all

    render json: @users
  end

  # GET /users/1
  def show
    render json: @user
  end

  # POST /users
  def create
    @user = User.new(user_params)


    if @user.save
      render json: @user, status: :created, location: @user
      UserNotifierMailer.send_signup_email(@user).deliver      
    else
      render json: @user.errors, status: :unprocessable_entity
    end
  end

  # PATCH/PUT /users/1
  def update
    if @user.update(user_params)
      render json: @user
    else
      render json: @user.errors, status: :unprocessable_entity
    end
  end

  # DELETE /users/1
  def destroy
    @user.destroy
  end

  private

  # Use callbacks to share common setup or constraints between actions.
  def set_user
    @user = User.find(params[:id])
  end

  # Only allow a trusted parameter "white list" through.
  def user_params
    params.require(:user).permit(:username, :password, :email)
  end
end

现在,当我从 Postman 向服务器发布数据时,它可以完美运行,并且可以很好地注册用户。

这是我从 Postman 那里得到的:

另一方面,我正在使用 Flutter 应用程序,并且正在尝试注册。

这是 Flutter 模型。

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

class HeadUser {
  User _user;

  HeadUser({User user}) {
    this._user = user;
  }

  HeadUser.fromJson(Map<String, dynamic> json) {
    _user = json['user'] != null ? new User.fromJson(json['user']) : null;
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    if (this._user != null) {
      data['user'] = this._user.toJson();
    }
    return data;
  }
}

class User {
  String _username;
  String _email;
  String _password;
  int _id;
  DateTime _createdAt;
  DateTime _updatedAt;

  User({int id, DateTime createdAt, DateTime updatedAt, String username, String email, String password}) {
    this._username = username;
    this._email = email;
    this._password = password;
    this._id = id;
    this._createdAt = createdAt;
    this._updatedAt = updatedAt;
  }

  factory User.fromJson(Map<String, dynamic> json) {
    return User(
    id: json['id'],
    username: json['username'],
    email: json['email'],
    createdAt: json['created_at'],
    updatedAt: json['updated_at'],
    );
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['username'] = this._username;
    data['email'] = this._email;
    data['password'] = this._password;
    return data;
  }
}

Future<HeadUser> loginUser(String url, {Map body}) async {
  return http.post(url, body: body).then((http.Response response) {
    final int statusCode = response.statusCode;
    if (statusCode < 200 || statusCode > 400 || statusCode == null) {
      throw new Exception("Error while posting data");
    }
    return HeadUser.fromJson(json.decode(response.body));
  });

}

我对这个的要求如下:

 onPressed: () async {
                          if (_formKey.currentState.validate())
                          {
                            HeadUser usr = new HeadUser(user: User(
                              email: this.emailEditingController.text.trim(),
                              password: this.passwordEditingController.text.trim(),
                              username: this.usernameEditingController.text.trim()
                            ));


                            HeadUser response = await loginUser(REGISTRATION_URL, body: usr.toJson());

但是当我这样做时,我的 Flutter 应用程序中出现错误,就像我缺少“用户”参数一样,虽然当我打印出来时它显示了确切的结构,但我明白了。

在这种情况下,请求甚至不会被触发,因此服务器不会受到攻击。

但是,如果我尝试在 loginUser 方法中执行 json.encode(body),那么我来自服务器的响应是:

当然,Flutter 也会抱怨:

我在这里做错了什么?

【问题讨论】:

  • Rails 接收的参数必须是{ user: { id: ..., name: ... } } 的形式,你现在发送的可能是{ id: ..., name: ... }
  • @SebastianPalma 谢谢你的提示。这不是问题,而是请求标头。

标签: ruby-on-rails json flutter dart ruby-on-rails-5.2


【解决方案1】:

好的,我实际上发现了一个问题(和一个解决方案)。

出于某种奇怪的原因,Rails 要求将数据显式发布为“Content-type”:“application/json”。

所以还需要设置请求头,并将它们传递给http.post 方法。

Future<HeadUser> loginUser(String url, {Map body}) async {
  Map<String, String> headers = {"Content-type": "application/json"};
  return http.post(url, headers: headers, body: json.encode(body)).then((http.Response response) {
    final int statusCode = response.statusCode;
    if (statusCode < 200 || statusCode > 400 || statusCode == null) {
      throw new Exception("Error while posting data");
    }
    return HeadUser.fromJson(json.decode(response.body));
  });

【讨论】:

  • 我看到了很多回应,但这个标题是问题所在!感谢 7 小时后,我得到了您的回复并解决了问题。
猜你喜欢
  • 2016-08-07
  • 2021-10-07
  • 2019-06-27
  • 1970-01-01
  • 2016-09-12
  • 1970-01-01
  • 2015-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多