when provided must microsoft management creating node.js azure azure-storage azure-mobile-services azure-storage-files

provided - Cargar un archivo en el almacenamiento de archivos de Azure usando node.js



portal azure free (5)

Cuando la solicitud llega a la función definida en exports.post , la solicitud completa ya está allí, por lo que no es necesario almacenarla. Puede simplificarlo escribiendo algo en la línea del código a continuación.

exports.post = function(request, response){ var shareName = request.headers.sharename; var dirPath = request.headers.directorypath; var fileName = request.headers.filename; var body = request.body; var length = body.length; console.log(length); try { fileService.createFileFromText(shareName, dirPath, fileName, body, function(error, result, resp) { if (!error) { // file uploaded response.send(statusCodes.OK, "File Uploaded"); } else { response.send(statusCodes.OK, "Error!"); } }); } catch (ex) { response.send(500, { error: ex.message }); } }

Estamos intentando crear un servicio web para cargar archivos en el almacenamiento de archivos de Azure mediante el servicio node.js.

A continuación se muestra el código del servidor node.js.

exports.post = function(request, response){ var shareName = request.headers.sharename; var dirPath = request.headers.directorypath; var fileName = request.headers.filename; var body; var length; request.on("data", function(chunk){ body += chunk; console.log("Get data"); }); request.on("end", function(){ try{ console.log("end"); var data = body; length = data.length; console.log(body); // This giving the result as undefined console.log(length); fileService.createFileFromStream(shareName, dirPath, fileName, body, length, function(error, result, resp) { if (!error) { // file uploaded response.send(statusCodes.OK, "File Uploaded"); }else{ response.send(statusCodes.OK, "Error!"); } }); }catch (er) { response.statusCode = 400; return res.end(''error: '' + er.message); } }); }

A continuación se muestra nuestro cliente para subir un archivo.

private static void sendPOST() throws IOException { URL obj = new URL("https://crowdtest-fileservice.azure-mobile.net/api/files_stage/"); HttpURLConnection con = (HttpURLConnection) obj.openConnection(); con.setRequestMethod("POST"); con.setRequestProperty("sharename", "newamactashare"); con.setRequestProperty("directorypath", "MaheshApp/TestLibrary/"); con.setRequestProperty("filename", "temp.txt"); Path path = Paths.get("C:/Users/uma.maheshwaran/Desktop/Temp.txt"); byte[] data = Files.readAllBytes(path); // For POST only - START con.setDoOutput(true); OutputStream os = con.getOutputStream(); os.write(data); os.flush(); os.close(); // For POST only - END int responseCode = con.getResponseCode(); System.out.println("POST Response Code :: " + responseCode); if (responseCode == HttpURLConnection.HTTP_OK) { // success BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); System.out.println(inputLine); } in.close(); // print result System.out.println(response.toString()); } else { BufferedReader br = new BufferedReader(new InputStreamReader(con.getErrorStream())); String line = ""; while ((line = br.readLine()) != null) { System.out.println(line); } System.out.println("POST request not worked"); } }

Esta mostrando el error

La solicitud ''POST / api / files_stage /'' ha caducado. Esto podría deberse a un script que no puede escribir en la respuesta o que, de lo contrario, no puede regresar de una llamada asíncrona de manera oportuna.

Actualizado:

También he intentado código debajo.

var body = new Object(); body = request.body; var length = body.length; console.log(request.body); console.log(body); console.log(length); try { fileService.createFileFromStream(shareName, dirPath, fileName, body, length, function(error, result, resp) { if (!error) { // file uploaded response.send(statusCodes.OK, "File Uploaded"); }else{ response.send(statusCodes.OK, "Error!"); } }); } catch (ex) { response.send(500, { error: ex.message }); }

Pero frente al problema

{"error": "El flujo de parámetros para la función createFileFromStream debería ser un objeto"}

Soy nuevo en node.js. Por favor ayúdame a arreglar esto.


Encuentro que la forma más fácil es usar pkgcloud que pkgcloud las diferencias entre los proveedores de la nube y también proporciona una interfaz limpia para cargar y descargar archivos. Utiliza flujos para que la implementación también sea eficiente en memoria.

var pkgcloud = require(''pkgcloud'') var fs = require(''fs'') var client = pkgcloud.storage.createClient({ provider: ''azure'', storageAccount: ''your-storage-account'', storageAccessKey: ''your-access-key'' }); var readStream = fs.createReadStream(''a-file.txt''); var writeStream = client.upload({ container: ''your-storage-container'', remote: ''remote-file-name.txt'' }); writeStream.on(''error'', function (err) { // handle your error case }); writeStream.on(''success'', function (file) { // success, file will be a File model }); readStream.pipe(writeStream);


Hay varias cosas:

1. createFileFromText puede trabajar con texto plano. Pero fallará para esos contenidos binarios, ya que utiliza la codificación UTF-8.

Es posible que desee hacer referencia al problema similar para blob en: Guardar blob (¡puede ser información!) Devuelto por la llamada AJAX a Azure Blob Storage crea una imagen dañada

2. La API de almacenamiento de Azure de createFileFromStream o createWriteStreamToExistingFile / createWriteStreamToNewFile puede ser la función que puede ayudar.

Tenga en cuenta que estas API están destinadas a las secuencias. Necesita convertir su búfer / cadena en el cuerpo de la solicitud a una secuencia. Puede referirse a ¿Cómo envolver un búfer como un flujo de lectura legible?

Para createFileFromStream :

fileService.createFileFromStream(req.headers.sharename, req.headers.directorypath, req.headers.filename, requestStream, data.length, function (error, result, resp) { res.statusCode = error ? 500 : 200; res.end(); } );

Para createWriteStreamToNewFile :

var writeStream = fileService.createWriteStreamToNewFile(req.headers.sharename, req.headers.directorypath, req.headers.filename, data.length); requestStream.pipe(writeStream);

3. Hay varios problemas en su código

console.log(body); // This giving the result as undefined

La razón es que usted define el var body y no está undefined . El body += chunk código body += chunk todavía hará que el body no esté definido.

fileService.createFileFromStream(shareName, dirPath, fileName, body, length, function(error, result, resp) { if (!error) { // file uploaded response.send(statusCodes.OK, "File Uploaded"); }else{ response.send(statusCodes.OK, "Error!"); } });

Cuando se produce un error en createFileFromStream , también podría tratarse de un error en la transferencia de red, es posible que también desee devolver el código de error en lugar de statusCodes.OK .


Hay varios problemas aquí. Vamos a repasarlos uno por uno.

1. En su cliente Java, no puede simplemente volcar los datos binarios en una conexión de servicio móvil de Azure.

La razón de esto es que un servicio móvil de Azure tiene dos analizadores de cuerpo que garantizan que, sin importar qué, el cuerpo de solicitud se analice para usted. Por lo tanto, si bien puede caminar por el analizador de cuerpo Express especificando un tipo de contenido poco común, seguirá presionando el analizador de cuerpo de Azure que desordenará su flujo de datos asumiendo ingenuamente que es una cadena UTF-8.

Por lo tanto, la única opción es omitir el analizador Express especificando un tipo de contenido que no puede manejar y luego jugar con el analizador de Azure mediante la codificación de sus datos binarios con la codificación Base64.

Por lo tanto, en el cliente Java reemplazar

Path path = Paths.get("C:/Users/uma.maheshwaran/Desktop/Temp.txt"); byte[] data = Files.readAllBytes(path);

con

con.setRequestProperty("content-type", "binary"); Path path = Paths.get("C:/Users/uma.maheshwaran/Desktop/Temp.txt"); byte[] data = Files.readAllBytes(path); data = Base64.getEncoder().encode(data);

Si no está en Java 8, reemplace el codificador java.util.Base64 con cualquier otro codificador Base64 al que tenga acceso.

2. La función de api de almacenamiento createFileFromStream Azure que está intentando usar espera una transmisión.

Al mismo tiempo, lo mejor que puede obtener al analizar manualmente un cuerpo de solicitud es una matriz de bytes. Desafortunadamente, los servicios móviles de Azure usan NodeJS versión 0.8, lo que significa que no hay una manera fácil de construir un flujo legible a partir de una matriz de bytes, y tendrá que ensamblar su propio flujo adecuado para la API de almacenamiento de Azure. Algunas cintas adhesivas y [email protected] deberían funcionar bien.

var base64 = require(''base64-js''), Stream = require(''stream''), fileService = require(''azure-storage'') .createFileService(''yourStorageAccount'', ''yourStoragePassword''); exports.post = function (req, res) { var data = base64.toByteArray(req.body), buffer = new Buffer(data), stream = new Stream(); stream[''_ended''] = false; stream[''pause''] = function() { stream[''_paused''] = true; }; stream[''resume''] = function() { if(stream[''_paused''] && !stream[''_ended'']) { stream.emit(''data'', buffer); stream[''_ended''] = true; stream.emit(''end''); } }; try { fileService.createFileFromStream(req.headers.sharename, req.headers.directorypath, req.headers.filename, stream, data.length, function (error, result, resp) { res.statusCode = error ? 500 : 200; res.end(); } ); } catch (e) { res.statusCode = 500; res.end(); } };

Estas son las dependencias que necesita para esta muestra.

"dependencies": { "azure-storage": "^0.7.0", "base64-js": "^0.0.8", "stream": "0.0.1" }

Si especificarlos en el paquete de su servicio. Json no funciona, siempre puede ir a este link e instalarlos manualmente a través de la consola.

cd site/wwwroot npm install azure-storage npm install base64-js npm install [email protected]

3. Para aumentar el límite de carga predeterminado de 1Mb, especifique MS_MaxRequestBodySizeKB para su servicio.

Tenga en cuenta que, dado que está transfiriendo sus datos como codificados en Base64, debe tener en cuenta esta sobrecarga. Por lo tanto, para admitir la carga de archivos de hasta 20 Mb de tamaño, debe configurar MS_MaxRequestBodySizeKB en aproximadamente 20 * 1024 * 4/3 = 27307.


Podemos aprovechar esta respuesta del hilo en SO ¿Cómo enviar una imagen desde el cliente de Android al servidor Node.js a través de HttpUrlConnection? , que crea un middleware personalizado para obtener el contenido del archivo cargado en una matriz de búfer, luego podemos usar createFileFromText() para almacenar el archivo en Azure Storage.

Aquí está el fragmento de código:

function rawBody(req, res, next) { var chunks = []; req.on(''data'', function (chunk) { chunks.push(chunk); }); req.on(''end'', function () { var buffer = Buffer.concat(chunks); req.bodyLength = buffer.length; req.rawBody = buffer; next(); }); req.on(''error'', function (err) { console.log(err); res.status(500); }); } router.post(''/upload'', rawBody,function (req, res){ fileService.createShareIfNotExists(''taskshare'', function (error, result, response) { if (!error) { // if result = true, share was created. // if result = false, share already existed. fileService.createDirectoryIfNotExists(''taskshare'', ''taskdirectory'', function (error, result, response) { if (!error) { // if result = true, share was created. // if result = false, share already existed. try { fileService.createFileFromText(''taskshare'', ''taskdirectory'', ''test.txt'', req.rawBody, function (error, result, resp) { if (!error) { // file uploaded res.send(200, "File Uploaded"); } else { res.send(200, "Error!"); } }); } catch (ex) { res.send(500, { error: ex.message }); } } }); } }); }) router.get(''/getfile'', function (req, res){ fileService.createReadStream(''taskshare'', ''taskdirectory'', ''test.txt'').pipe(res); })