Saltar al contenido

Angular: serializar / unserializar en el objeto JSON HttpRequest y HttpResponse

Solución:

Aunque recomendaría un Service Worker para el almacenamiento en caché, la forma más fácil que conozco es clonar la solicitud / respuesta y luego obtener su información:

function serializeRequest(req: HttpRequest<any>): string {
    const request = req.clone(); // Make a clone, useful for doing destructive things
    return JSON.stringify({
        headers: Object.fromEntries( // Just a helper to make this into an object, not really required but makes the output nicer
            request.headers.keys.map( // Get all of the headers
                (key: string) => [key, request.headers.getAll(key)] // Get all of the corresponding values for the headers
            )
        ),
        method: request.method, // The Request Method, e.g. GET, POST, DELETE
        url: request.url, // The URL
        params: Object.fromEntries( // Just a helper to make this into an object, not really required but makes the output nicer
            request.headers.keys.map( // Get all of the headers
                (key: string) => [key, request.headers.getAll(key)] // Get all of the corresponding values for the headers
            )
        ), // The request parameters
        withCredentials: request.withCredentials, // Whether credentials are being sent
        respnseType: request.responseType, // The response type
        body: request.serializeBody() // Serialize the body, all well and good since we are working on a clone
    })
}

De manera similar, también podemos serializar la respuesta (asumiendo T es compatible con JSON, una suposición justa en una solicitud HTTP):

function serializeResponse(res: HttpResponse<any>): string {
    const response = res.clone();
    return JSON.stringify({
        headers: Object.fromEntries( // Just a helper to make this into an object, not really required but makes the output nicer
            response.headers.keys.map( // Get all of the headers
                (key: string) => [key, response.headers.getAll(key)] // Get all of the corresponding values for the headers
            )
        ),
        status: response.status,
        statusText: response.statusText,
        url: response.url,
        body: response // Serialize the body, all well and good since we are working on a clone
    })
}

Y luego, dado que guardamos toda la información requerida, la deserialización es un paseo por el parque:

function deserializeRequest<T = any>(req: string): HttpRequest<T> {
    const request = JSON.parse(req);
    const headers = new HttpHeaders(request.headers);
    const params = new HttpParams(); // Probably some way to make this a one-liner, but alas, there are no good docs
    for(let parameter in request.params){
        request.params[parameter].forEach((paramValue: string) => params.append(parameter, paramValue));
    }
    return new HttpRequest(request.method, request.url, request.body, {
        headers,
        params,
        respnseType: request.respnseType,
        withCredentials: request.withCredentials
    });
}

function deserializeResponse<T = any>(res: string): HttpResponse<T> {
    const response = JSON.parse(res);
    const headers = new HttpHeaders(response.headers);
    return new HttpRequest({
        headers,
        body: response.body,
        status: response.status,
        statusText: response.statusText,
        url: response.url,
    });
}

Zona de juegos de todo (aunque, lamentablemente, los tipos angulares no se cargan correctamente)

Tenga en cuenta que no he probado esto en ningún entorno, por lo que se proporciona TAL CUAL, y no estoy seguro de cómo expect manejaría dos HttpHeaders/HttpParams, especialmente porque es posible que no tengan exactamente el mismo orden.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *