XMLHttpRequest PDF


([N1] robertocofiex) #1

Hola, estoy intentando conectar a través de XMLHttpRequest al servidor de la AEAT para la presentación y obtención de las declaraciones de IVA etc.

Para imprimir un modelo 131( Se podrá hacer con cualquier otro 303,202,etc) se envían unos datos en POST y la AEAT devuelve un pdf.

Con el envío que hago de datos el xhr.errorCode es 0 xhr.status es 200 es decir todo ok.

El problema es que los datos que recibo en xhr.response es:

%PDF-1.4
%???
3 0 obj
<</Filter/FlateDecode/Length 467>>stream
x???An?0E?:?,[??p??P?N???A+?4t??6???z???drb5?

Lo guardo en un fichero pdf. pero es un fichero dañado. Entiendo que se devuelve el pdf en otro formato pero no se continuar.

Ayuda???.

Saludos.


([N1] wikan) #2

Dudo mucho que la AEAT te deje acceder usando una simple conexión enviando la información por POST. Cualquier podría acceder a la información de otro.


([N1] robertocofiex) #3

Efectivamente, Hacienda no ofrece datos privados pero es un envió de predeclaracion, envías los datos los valida y emite el PDF, lo imprimes, se paga en entidades bancarias y ok. No se hace ninguna presentación ni nada por eso el acceso al servicio es libre… Es un servicio de validación e impresión.

Puedo pasar toda la información pero mi dificultad es en cómo se recibe de la AEAT el PDF.

No me importaría compartir todo lo que se de la construcción y datos para la presentación de declaraciones en la AEAT. El avance sería muy positivo para la comunidad Velneo.

Muchas Gracias wikan por responder. Creo que el tema es cómo se reciben y convierten los datos recibidos.


([N1] wikan) #4

Prueba a recibir por VByteArray y luego a guardarlo en un fichero como PDF.


([N1] robertocofiex) #5

Gracias, pero esto es lo que no se hacer.¿ Como es?


([N1] wikan) #6

Especifica el responseType

Tienes los ejemplos en la parte inferior.


([N1] cristianvg2003) #7

Hola, prueba con mi libreria de para manejo de http request,

en el readme =>vajax vas a ver dos ejemplos de como descargar binarios.

Un saludo,


([N1] robertocofiex) #8

Siguiendo vuestras indicaciones he hecho este código. Me crea el pdf pero no le meto nada. En cambio sí existe respuesta del servidor.

Pongo el código entero. Por los datos de la variable “fic” no os preocupéis porque son los mios personales y es todo inventado.

A ver si podéis ayudarme. Muchas gracias.


importClass(“XMLHttpRequest”);
importClass( “VFile” );

var url=“https://www6.aeat.es/wlpl/PFTW-PICW/ServVali”;

var xhr=new XMLHttpRequest();
xhr.setRequestHeader(‘Content-Type’, ‘application/x-www-form-urlencoded’);

xhr.open(“POST”, url,false);
var fic="<T131020171T0000><AUX> 5.90 B10459873 </AUX><T13101000> I44401428CGARCIA MARTIN ROBERTO 20171T6471000000000009861200020000000000000019722 000000000000000000000000000000000000000 000000000000000000000000000000000000000 000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000009861200000000000001972200000000000000000000000000000000000000000000000000000000000000000000000000000000197220000000000000000000000000000000000000000000000197220000000000000000000000000000000000000000000000197220000000000000000000000000000019722 </T13101000></T131020171T0000>";
var datos=“HID=IE51310A&IDI=ES&LEV=000000000000&FIC=”+fic+"&RUT=&PRG=&FIN=&EJF=2017&MOD=131";

xhr.send(datos);

alert(xhr.status);
alert(xhr.response);

if((xhr.errorCode==0)&&(xhr.status==200)){

var fi = new VFile( “C://a.pdf” );

if ( fi.open( VFile.OpenModeWriteOnly | VFile.OpenModeTruncate) ) {
	alert(xhr.response);
	
				fi.write(xhr.response);
				fi.close();
			}
			else
				{
					alert( "No se pudo abrir el fichero" );
				}
}


([N1] wikan) #9

Sigues sin definir la respuesta como VByteArray, estarás recibiendo un string puro y duro.


([N3] pacosatu) #10

Hola robertocofiex.

Como te está indicando Manuel (y no le haces caso) debes decirle a la clase XmlHttpRequest que el resultado obtenido en XMLHttpRequest.response lo entregue tal cual y sin conversiones de formato. Esto se realiza con la propiedad XMLHttpRequest.responseType.

Como ya nos tiene acostumbrados, la documentación de Velneo es confusa y no aclara para nada su funcionamiento.
A la propiedad responseType se le pueden asignar 3 valores:

  • Cadena vacía -> El valor por defecto. ¡¡OJO!! en este caso la codificación de XMLHttpRequest.response será siempre UTF-8. Si lo que estamos esperando es Texto codificado como ISO-8859-1/15, tendremos que tenerlo en cuenta.
  • json” -> La propiedad XMLHttpRequest.response contendrá un objeto JSON de javascript. Lo que hace Velneo es convertir el texto recibido en el response y parsearlo en un objeto JSON. Nos ahorra el comando JSON.parse(XMLHttpRequest.response).
  • arraybuffer” -> La propiedad XMLHttpRequest.response contendrá un objeto VByteArray del API de Velneo. En este caso Velneo no realiza conversiones de ningún tipo, nos entrega los datos del response tal cual le han llegado.

En tu caso, por lo tanto, si dejas la propiedad responseType en blanco, Velneo te entrega el PDF como un String en formato UTF-8 que no tiene nada que ver con el contenido binario que tiene un fichero PDF y de allí viene el fallo.

Asigna el valor XMLHttpRequest.responseType = “arraybuffer” antes de enviar el request y verás como todo funciona bien.

Sin embargo, no todo es tan fácil. ¿Cómo sabemos que el contenido de response es un PDF o Texto plano?
Pues debemos consultar la cabecera Content-Type del response.

En tu caso, tendremos 2 tipos de contenido:
1º.- Content-Type = “application/pdf” -> Los datos del response son un bufer binario PDF
2º.- Content-Type = “text/html; charset=ISO-8859-1” -> Ha ocurrido un Error en la validación del modelo 131

Así, consultando el valor de la cabecera Content-Type sabremos que extensión asignamos al fichero de disco, pdf o html.

De forma resumida, tu ejemplo quedaría:

importClass("XMLHttpRequest")
importClass( "VFile" )
importClass("VProcess");

var xhr = new XMLHttpRequest()

// **************************************************************
// Validación del registro para el modelo 131 de la AEAT

// Indicamos que no haya modificación de los datos recibidos
xhr.responseType = "arraybuffer"
// Tipo de dato del Request
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
// Abrimos conexión
xhr.open("POST", "https://www6.aeat.es/wlpl/PFTW-PICW/ServVali", false)
// Datos para la validación del Registro del Modelo 131 de la AEAT
var cDatos = "\
HID=IE51310A&IDI=ES&LEV=000000000000&FIC=<T131020171T0000><AUX>                                     \
                                 5_90    B10459873                                                  \
                                                                                                    \
                                                               </AUX><T13101000> I44401428CGARCIA MA\
RTIN                                               ROBERTO             20171T64710000000000098612000\
20000000000000019722    000000000000000000000000000000000000000    000000000000000000000000000000000\
000000    000000000000000000000000000000000000000    00000000000000000000000000000000000000000000000\
0009861200000000000001972200000000000000000000000000000000000000000000000000000000000000000000000000\
0000001972200000000000000000000000000000000000000000000001972200000000000000000000000000000000000000\
00000000197220000000000000000000000000000019722                                                     \
                                                                                                    \
        </T13101000></T131020171T0000>&RUT=&PRG=&FIN=&EJF=2017&MOD=131"

// Enviamos el Request
xhr.send(cDatos)

if (parseInt(xhr.status) == 200) {
	var cTipo_Respuesta = xhr.getResponseHeader("Content-Type")
	var cNombre_fichero = ""
	if (cTipo_Respuesta) {
		switch(cTipo_Respuesta.match(/(\w+\/)/)[0]) {
			case "text/":
				// El byteArray es texto HTML codificado como Latin1 (ISO-8859-1)
				var cNombre_fichero = theApp.clientCachePath() + "_aeat_validar_error.html"
				break;
			case "application/":
				// Tenemos un byteArray con el PDF
				var cNombre_fichero = theApp.clientCachePath() + "_aeat_validar_borrador.pdf"
				break;
		}
	}
	if (cNombre_fichero) {
		// Guardamos el resultado en fichero de disco
		var oFile = new VFile(cNombre_fichero)
		if ( oFile.open( VFile.OpenModeWriteOnly | VFile.OpenModeTruncate) ) {
                        // Guardamos directamente el bytearray a disco
			oFile.write(xhr.response)
			oFile.close()
			// Visualizar documento desde Velneo -> Ejecutar documento (CPATH_FICHERO)
			var oProceso = new VProcess(theRoot)
			oProceso.setProcess("MiApp/PRO_VER_DOCUMENTO")
			oProceso.setVar("CPATH_FICHERO", cNombre_fichero)
			oProceso.exec()
		} else {
			// Si no ha sido posible abrir el fichero se muestra error
			alert( "No se pudo crear el fichero " + oFile.fileName(), "Error" );
		}
	}
}

Saludos
Paco Satué


([N1] robertocofiex) #11

Efectivamente faltaba el detalle apuntado por Manuel. Gracias a todos funciona perfectamente.

Sigo con ello, ahora estoy con la firma digital. Necesito leer un fichero con la firma electronica e incluirlo en los datos para enviar. Como está codificado y lo tengo que concatenar con los datos enviados en el POST, ¿Debo utilizar algún tipo de variable especial??

Por si es de vuestro interés lo que estoy realizando es la conexión, presentación y descarga de la AEAT de los impuestos de manera desatendida, para que la presentación sea directa, sin navegador y sin intervención del usuario.

Nuevamente muchas gracias.