Ionic / Angular JS - отправить форму с изображением на PHP

Я создаю мобильное приложение, используя Ionic/Angular JS. На определенной вкладке пользователь может заполнить форму и выбрать изображение с помощью плагина ngCordova Camera Plugin и отправить форму. Я хотел бы отправить все детали формы www.mydomain.com/receive.php.

Вот как выглядит мой HTML-файл для этой конкретной вкладки:

<ion-view view-title="Form">
  <ion-content>
    <div class="list">
        <div class="item item-divider">
          Personal Details
        </div>
        <label class="item item-input">
          <span class="input-label">Name</span>
          <input name="fname" type="text" placeholder="John">
        </label>
        <label class="item item-input">
          <span class="input-label">Surname</span>
          <input name="lname" type="text" placeholder="Smith">
        </label>
        <label class="item item-input">
          <span class="input-label">Email</span>
          <input name="email" type="email" placeholder="[email protected]">
        </label>
        <label class="item item-input">
          <span class="input-label">Phone</span>
          <input name="phone" type="tel" placeholder="555234567">
        </label>
        <div class="item item-divider">
          Location
        </div>
        <button class="button button-full button-balanced" ng-click="getLocation()"><i class="ion-android-locate"></i> Get my location</button>
        <label class="item item-input">
          <span class="input-label">Street</span>
          <input name="street" type="text" ng-model="pStreet.value">
        </label>
        <label class="item item-input">
          <span class="input-label">Number</span>
          <input name="number" type="text" ng-model="pNumber.value">
        </label>
        <label class="item item-input hidden">
          <span class="input-label">Lat</span>
          <input name="lat" type="text" ng-model="pLat.value">
        </label>
        <label class="item item-input hidden">
          <span class="input-label">Lng</span>
          <input name="lng" type="text" ng-model="pLng.value">
        </label>
        <label class="item item-input hidden">
          <span class="input-label">Address</span>
          <input name="address" type="text" ng-model="pAddress.value">
        </label>
        <div class="item item-divider">
          Photo
        </div>
        <div class="item">
          <div class="row">
            <div class="photo">
              <button ng-click="selectPicture()">Select Picture</button>
              <img id="myImage" style="width: 100%; height: auto;"/>
            </div>
          </div>
        </div>
        <button class="button button-full button-positive" ng-click="">Send form</button>
      </div>
  </ion-content>
</ion-view>

А вот и Controller JS для вкладки:

.controller('PetitionsCtrl', function($scope, $cordovaGeolocation, $cordovaCamera, $log, $ionicLoading, $http, $timeout, $compile) {

  $scope.getLocation = function() {
    $ionicLoading.show({
      templateUrl: 'loading.html',
      hideOnStateChange: true
    });
      var posOptions = {timeout: 15000, enableHighAccuracy: true};
      $cordovaGeolocation
      .getCurrentPosition(posOptions)
      .then(function (position) {
        $scope.lat = position.coords.latitude;
        $scope.lng = position.coords.longitude;
        $scope.pLat = {value: $scope.lat};
        $scope.pLng = {value: $scope.lng};

        var geocoder = new google.maps.Geocoder();
        var latlng = new google.maps.LatLng($scope.lat, $scope.lng);
        var request = {
          latLng: latlng
        };

        geocoder.geocode(request, function(data, status) {
          if (status == google.maps.GeocoderStatus.OK) {
            if (data[0] != null) {
              $scope.$apply(function () {
                $scope.pStreet = {value: data[0].address_components[0].types[0] === 'route' ? data[0].address_components[0].long_name : data[0].address_components[1].long_name};
                $scope.pNumber = {value: data[0].address_components[0].types[0] === 'street_number' ? data[0].address_components[0].long_name : ''};
                $scope.pAddress = {value: data[0].formatted_address};
                setTimeout(function () {
                  $ionicLoading.hide();
                }, 500);
              });
            } else {
              setTimeout(function () {
                $ionicLoading.hide();
              }, 500);
            }
          }
        })
      });
    };

    $scope.selectPicture = function() {

      var options = {
        quality: 90,
        destinationType: Camera.DestinationType.DATA_URL,
        sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
        allowEdit: false,
        encodingType: Camera.EncodingType.JPEG,
        popoverOptions: CameraPopoverOptions,
        saveToPhotoAlbum: false,
        correctOrientation: true
      };

      $cordovaCamera.getPicture(options).then(function(imageData) {
        var image = document.getElementById('myImage');
        image.src = "data:image/jpeg;base64," + imageData;
      }, function(err) {
        // err
      });

    }

})

Я нуб, когда мы говорим об Ionic / Angular (эксперт по PHP, поэтому я позабочусь об этом). Как я могу передать данные формы, включая imageDate, в PHP?


person Ganikkost    schedule 24.11.2016    source источник
comment
Здравствуйте, вы думали о том, чтобы прочитать изображение с помощью холста/другого метода и упаковать его в скрытое поле? Затем вы можете отправить его обратно на сервер, используя форму без дополнительной работы.   -  person Mathieu de Lorimier    schedule 24.11.2016
comment
Да, я пытался создать скрытое поле вроде этого: ‹input name=photo type=text ng-model=pPhoto.value› и добавил это в Controller.JS: $scope.pPhoto = {value: data:image/jpeg ;base64, + imageDat}; но это не работает.   -  person Ganikkost    schedule 24.11.2016
comment
Это дает вам ошибку? Можете ли вы поделиться остальным кодом?   -  person Mathieu de Lorimier    schedule 24.11.2016
comment
Ошибок нет, но поле не заполнено данными. Вот обновленный код: jsfiddle.net/r0pcetf4   -  person Ganikkost    schedule 24.11.2016
comment
Я предполагаю, что вам может понадобиться выполнить $scope.apply() после присвоения значения pPhoto, поскольку вы находитесь в неугловом обратном вызове. Но я могу ошибаться.   -  person Mathieu de Lorimier    schedule 24.11.2016


Ответы (2)


Андрей.

Вам нужно связать каждую модель ввода html. бывший.

    <label class="item item-input">
      <span class="input-label">Name</span>
      <input name="fname" type="text" placeholder="John" ng-model="myForm.fname">
    </label>
    <label class="item item-input">
      <span class="input-label">Surname</span>
      <input name="lname" type="text" placeholder="Smith" ng-model="myForm.lname">
    </label>

Ваш контроллер.

  $cordovaCamera.getPicture(options).then(function(imageData) {
    var image = document.getElementById('myImage');
    image.src = "data:image/jpeg;base64," + imageData;

    // You want to send the data
    $rootScope.data = {
      src : "data:image/jpeg;base64," + imageData,
      fname : $scope.myForm.fname,
      lname : $scope.myForm.lname
    }
  }, function(err) {
    // err
  });

Ваш $http.

var url = "www.mydomain.com/receive.php";
      $http({
        method: 'POST',
        data: $rootScope.data,
        url: url
      }).
      then(function (response) {
         //ok
      }, function (response) {
         //fail
      });

Ваш PHP.

$src = $_REQUEST['src'];
$fname = $_REQUEST['fname'];
$lname = $_REQUEST['lname'];

Этот код может сохранить ваши изображения.

    $base64_string_img = $src;
    $data = explode(',', $base64_string_img);
    $filename_path = md5(time() . uniqid()) . ".jpg";
    $decoded = base64_decode($data[1]);
    file_put_contents("uploads/" . $filename_path, $decoded);
person Chaoyenpo    schedule 24.11.2016

для этого мы используем плагин, это самый простой способ: https://github.com/apache/cordova-plugin-file-transfer

Согласно документации:

var win = function (r) {
    console.log("Code = " + r.responseCode);
    console.log("Response = " + r.response);
    console.log("Sent = " + r.bytesSent);
}

var fail = function (error) {
    alert("An error has occurred: Code = " + error.code);
    console.log("upload error source " + error.source);
    console.log("upload error target " + error.target);
}

var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = fileURL.substr(fileURL.lastIndexOf('/') + 1);
options.mimeType = "text/plain";

var params = {};
params.value1 = "test";
params.value2 = "param";

options.params = params;

var ft = new FileTransfer();
ft.upload(fileURL, encodeURI("http://some.server.com/upload.php"), win, fail, options);
person Gerardo Rosciano    schedule 24.11.2016
comment
Видел уже этот плагин. Проблема в том, что этот плагин отправляет только файл. Мне также нужно опубликовать информацию обо всех других полях. - person Ganikkost; 24.11.2016