【问题标题】:Sending an image via a post request from an Ionic app to a rails endpoint通过 Ionic 应用程序的 post 请求将图像发送到 rails 端点
【发布时间】:2015-07-27 10:32:52
【问题描述】:

我目前正在开发一个 Ionic 移动应用程序,该应用程序最终将拍照、附加位置并在发布请求中将它们发送到 Rails 端点。在查看了 linklink 以及无数其他人之后,我一直无法找到任何有关实现此特定功能的可靠信息。

我可以使用 html 输入表单通过浏览器上传照片,然后将其添加到数据库中,并通过 get 请求显示在应用程序上。

但是,当在手机上拍照并尝试直接从应用通过发布请求发送照片时,只接收到位置信息,图像未正确编码。

这是接收到的 JSON 数据,它返回 "image_url":"/images/main/missing.png"

    { "id":6,"city":"Greater London",
      "country":"United Kingdom","created_at":"2015-05-14T21:22:22.825Z",
      "updated_at":"2015-05-14T21:22:22.825Z","image_file_name":null,
      "image_content_type":null,"image_file_size":null,
      "image_updated_at":null,"image_url":"/images/main/missing.png" }

代码如下:

Angular 工厂发出帖子请求:

.factory('Posts', function($http) {

  var o = { posts: [] };

  o.getAll = function() {
    return  $http.get('http://localhost:8100/posts').success(function(data) {
      angular.copy(data, o.posts);
    });
  };

  o.addPost = function(post) {
    return $http.post('https://shielded-hamlet-4665.herokuapp.com/posts', post);
  };

  return o;
})

Angular 控制器拍照:

.controller("CameraCtrl", function($scope, $cordovaCamera, $http, Posts) {

  var id = 0;

  var options = { 
    quality : 75, 
    destinationType : Camera.DestinationType.FILE_URI, 
    sourceType : 1, 
    allowEdit : true,
    encodingType: 0,
    targetWidth: 380,
    targetHeight: 450,
    popoverOptions: CameraPopoverOptions,
    saveToPhotoAlbum: false
  };

  function getLocCoords(position) {
    $scope.lat = position.coords.latitude;
    $scope.lon = position.coords.longitude;

    $http.get('http://maps.googleapis.com/maps/api/geocode/json?latlng=' + $scope.lat +',' + $scope.lon + '&sensor=true')
      .success(function(data) {

        var home = data.results[0].address_components;

        for (var i = 0; i < home.length; i++) {
          if(home[i].types.indexOf("administrative_area_level_2") > -1) {
            $scope.city = home[i].long_name;
            break;
          };
        };

        for (var i = 0; i < home.length; i++) {
          if(home[i].types.indexOf('country') > -1) {
            $scope.country = home[i].long_name;
            break;
          };
        };
      })
  };

  $scope.takePicture = function() {

    navigator.geolocation.getCurrentPosition(getLocCoords);

    $cordovaCamera.getPicture(options).then(function(imageData) {
      $scope.imgURI = imageData;
      id ++;
      var post = { id: id, country: $scope.country, city: $scope.city, image: $scope.imgURI, likes: 0, comments: [] }
      Posts.addPost(post);
    }, function(err) {

    });
  }

Rails 数据库中的 Post 控制器:

class PostsController < ApplicationController

  skip_before_filter :verify_authenticity_token

  def index
    @posts = Post.all
    render json: @posts, :callback => params['callback'], :content_type => 'application/javascript', :methods => [:image_url]
  end

  def new
    @post = Post.new
  end

  def create
    Post.create(post_params)
    redirect_to '/posts'
  end

  def post_params
    params.require(:post).permit(:city, :country, :image)
  end

end

我没有对离子框架做很多工作,所以请原谅我的无知。任何帮助将不胜感激。

【问题讨论】:

    标签: ruby-on-rails angularjs cordova http-post ionic-framework


    【解决方案1】:

    设法使用cordovaFileTransfer.upload 方法解决了这个问题。

    rails 端点也在过滤参数并寻找带有图像字符串的帖子对象,并且只提供了一个图像字符串。

    下面的代码现在可以工作了

    Angular 工厂发出帖子请求:

    .factory('Posts', function($http, $cordovaFileTransfer) {
    
      var o = { posts: [] };
    
      o.getAll = function() {
        return $http.get('https://shielded-hamlet-4665.herokuapp.com/posts').success(function(data) {
          angular.copy(data, o.posts);
        });
      };
    
      o.addPost = function(post) {
    
        var options = {
          fileKey: "image",
          fileName: "image.jpeg",
          chunkedMode: false,
          mimeType: "image/jpeg",
          params: { city: post.city, country: post.country, lat: post.lat, lon: post.lon }
        };
    
        $cordovaFileTransfer.upload('http://shielded-hamlet-4665.herokuapp.com/posts', post.image, options)
          .then(function(result){
            console.log("Code = ok");
          }, function(error){
            console.log("Code = " + error);
          }, function(progress){});
      };
    
      return o;
    })
    

    Angular 控制器拍照:

    .controller("CameraCtrl", function($scope, $cordovaCamera, $http, Posts) {
    
      post = {};
    
      var options = { 
        quality : 75, 
        destinationType : Camera.DestinationType.FILE_URI, 
        sourceType : 1,
        allowEdit : true,
        encodingType: 0,
        targetWidth: 380,
        targetHeight: 450,
        popoverOptions: CameraPopoverOptions,
        saveToPhotoAlbum: false
      };
    
      function getLocCoords(position) {
        post.lat = position.coords.latitude;
        post.lon = position.coords.longitude;
    
        $http.get('http://maps.googleapis.com/maps/api/geocode/json?latlng=' + post.lat +',' + post.lon + '&sensor=true')
          .success(function(data) {
    
            var home = data.results[0].address_components;
    
            for (var i = 0; i < home.length; i++) {
              if(home[i].types.indexOf("administrative_area_level_2") > -1) {
                post.city = home[i].long_name;
                break;
              };
            };
    
            for (var i = 0; i < home.length; i++) {
              if(home[i].types.indexOf('country') > -1) {
                post.country = home[i].long_name;
                break;
              };
            };
          })
      };
    
      $scope.takePicture = function() {
    
        navigator.geolocation.getCurrentPosition(getLocCoords);
    
        $cordovaCamera.getPicture(options).then(function(imageData) {
          post.image = imageData;
          Posts.addPost(post);
        }, function(err) {});
      };
    });
    

    来自 rails 数据库的后控制器:

    class PostsController < ApplicationController
    
      skip_before_filter :verify_authenticity_token
    
      def index
        @posts = Post.all
        render json: @posts, :callback => params['callback'], :content_type => 'application/javascript', :methods => [:image_url]
      end
    
      def new
        @post = Post.new
      end
    
      def create
        Post.create(post_params)
        redirect_to '/posts'
      end
    
      def post_params
        params.permit(:city, :country, :image, :lat, :lon)
      end
    
    end
    

    【讨论】:

      猜你喜欢
      • 2021-08-02
      • 2020-07-08
      • 2018-04-20
      • 2020-05-12
      • 2014-02-19
      • 2015-07-24
      • 2019-11-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多