Рассмотрим пример загрузки файла с мобильного устройства на удаленный сервер. Условимся, что у нас могут быть разные варианты приема отправленного файла на стороне сервера:
- прием файла посредством PHP;
- прием файла посредством Node.js
Плагины и доступы
Для начала нам нужно установить необходимые плагины для работы с загружаемыми файлами:
cordova plugin add cordova-plugin-file cordova plugin add cordova-plugin-file-transfer cordova plugin add cordova-plugin-white-list cordova plugin add cordova-plugin-camera cordova plugin add cordova-plugin-device
Далее даем доступы на права работы с файлами и с сетями платформе. К примеру. для Android они задаются в файле в папке по пути MyApp\platforms\android\app\src\main\AndroidManifest.xml:
<?xml version='1.0' encoding='utf-8'?> <manifest android:hardwareAccelerated="true" android:versionCode="10000" android:versionName="1.0.0" package="io.cordova.hellocordova" xmlns:android="http://schemas.android.com/apk/res/android"> <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> ...
Клиентский код
Кнопка открытия. Обращаем внимание на meta — тег с разрешениями на удаленную передачу:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'"> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <meta name="format-detection" content="telephone=no"> <meta name="msapplication-tap-highlight" content="no"> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width"> <link rel="stylesheet" type="text/css" href="css/index.css"> </head> <body> <button id="getImage">Выбрать картинку</button> <script src="cordova.js" ><script> <script src="index.js" ><script> </body> </html>
Скрипт:
var app = { initialize: function() { this.bindEvents(); this.setupApp(); }, bindEvents: function() { document.addEventListener('deviceready', this.onDeviceReady, false); }, onDeviceReady: function() { app.receivedEvent('deviceready'); }, receivedEvent: function(id) { console.log('Received Event: ' + id); }, setupApp: function(){ function getImage() { navigator.camera.getPicture( this.uploadPhoto, function (message) { alert('get picture failed'); }, { quality: 50, destinationType: navigator.camera.DestinationType.FILE_URI, sourceType: navigator.camera.PictureSourceType.PHOTOLIBRARY } ); } function uploadPhoto(imageURI) { alert(imageURI); var options = new FileUploadOptions(); options.fileKey = "file"; options.fileName = imageURI.substr(imageURI.lastIndexOf('/') + 1); options.mimeType = "image/jpeg"; var params = {}; params.value1 = "test"; params.value2 = "param"; options.params = params; var ft = new FileTransfer(); ft.upload( imageURI, encodeURI("http://83.220.168.205/upload/upload.php"), this.win, this.fail, options); } function win(r) { console.log("Code = " + r.responseCode); console.log("Response = " + r.response); console.log("Sent = " + r.bytesSent); } function fail(error) { alert("An error has occurred: Code = " + error.code); console.log("upload error source " + error.source); console.log("upload error target " + error.target); alert("upload error source " + error.source); alert("upload error target " + error.target); } document.getElementById("getImage").onclick = function() { getImage(); }; } } app.initialize();
Серверный код на PHP
Сначала в корне сервера надо создать папку upload и в ней файл upload.php и подпапку upload, куда будут файлы грузиться и храниться:
<?php //Задаем заголовки на стороний доступ header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, PATCH, DELETE'); header('Access-Control-Allow-Headers: X-Requested-With,content-type'); header('Access-Control-Allow-Credentials: true'); // $new_image_name = urldecode($_FILES["file"]["name"]).".jpg"; //Переносим файл в нужную папку move_uploaded_file($_FILES["file"]["tmp_name"], "upload/".$new_image_name); ?>
Обращаем внимание на заголовки, которые разрешают доступ со стороны клиента.
Серверный код на JavaScript для Node.js
Если требуется загрузить и заполучить файл со стороны Node.js, то легче все это сделать при помощи стороннего модуля express-formidable, если приложение express. Сначала устанавливаем сам модуль:
npm install express-formidable
Далее дописываем наш app.js на прием. К пример, у нас есть url — адрес http://myhostname:3000/upload, то код для приема и сохранения загруженного с клиента файла будет следующим:
var formidable = require('formidable'); ... app.post('/upload', function(req, res) { res.set({ 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS, PUT, PATCH, DELETE', 'Access-Control-Allow-Headers': 'X-Requested-With,content-type', 'Access-Control-Allow-Credentials': 'true' }); //var data = req.body; //console.log(data); //console.log(req.files); var form = new formidable.IncomingForm(); form.parse(req); form.on('fileBegin', function (name, file){ file.path = __dirname + '/upload/' + file.name + '.jpg'; }); form.on('file', function (name, file){ console.log('Uploaded ' + file.name); }); });