通过从Ionic应用程序到rails端点的发布请求发送图像

时间:2015-05-15 13:16:51

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

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

我可以使用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;
})

角度控制器拍照:

.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 Controller:

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

我还没有对离子骨架做过大量的工作,所以请原谅我的无知。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

使用cordovaFileTransfer.upload方法管理解决此问题。

导轨终点还过滤了params并查找了一个带有图像字符串的post对象,并且只提供了一个图像字符串。

以下代码正在运行

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;
})

角度控制器拍照:

.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