Добавление нового заголовка в запрос с сохранением тела - PullRequest
0 голосов
/ 11 февраля 2019

Я настраиваю PWA для своей компании в домашних условиях.Какой метод я должен использовать, чтобы прикрепить токен на предъявителя ко всем запросам от dom или веб-работника.

Этот метод, который я использую, работает, как и ожидалось, при публикации form или json, но я быкак более чистый или дружественный метод, так как я не верю, что запасного варианта text будет достаточно.

Я искал функцию в служебном модуле Google workbox.js, чтобы посмотреть, смогу ли я установить перехватвсегда добавлять маркер Bearer, когда на мой сервер делается запрос, так как это решило бы проблему, почему я оказался здесь в первую очередь.Этот код основан на настройке Firebase Service Worker .И не было ничего, чтобы получить и повторно добавить данные записи в новый запрос, таким образом, фактически удалив все тело POST.

Это код, с которым я закончил.

self.addEventListener( 'fetch', ( event ) => {
    const requestProcessor = async ( idToken ) => {

        let req = event.request;

        // For same origin https requests, append idToken to header.
        if ( self.location.origin == getOriginFromUrl( event.request.url ) &&
            ( self.location.protocol == 'https:' ||
                self.location.hostname == 'localhost' ) &&
            idToken ) {


            let contentType = req.headers.get( "Content-Type" );

            // Clone headers as request headers are immutable.
            const headers = new Headers();
            for ( let entry of req.headers.entries() ) {
                headers.append( entry[ 0 ], entry[ 1 ] );
            }
            // Add ID token to header.
            headers.append( 'Authorization', 'Bearer ' + idToken );
            try {

                let tmpReq = req.clone();
                let body = "";

                if ( req.body ) {
                    body = req.body;

                } else if ( req.method === "POST" ) {
                    // get the post data if its json
                    if ( contentType === "application/json" ) {
                        // get JSON data
                        let json = await tmpReq.json();
                        body = JSON.stringify( json );

                    // Get the post data if its a submitted form
                    } else if ( contentType === "application/x-www-form-urlencoded" ) {
                        // get Form-Data
                        body = await tmpReq.formData();

                    // Get the post data as plain text as a fallback
                    } else {
                        body = await tmpReq.text();
                    }

                    console.log( "Content", content );
                }

                // create a new request with the Bearer Token and post body
                req = new Request( req.url, {
                    method: req.method,
                    headers: headers,
                    mode: 'same-origin',
                    credentials: req.credentials,
                    cache: req.cache,
                    redirect: req.redirect,
                    referrer: req.referrer,
                    body: body,
                    bodyUsed: req.bodyUsed,
                    context: req.context
                } );

            } catch ( e ) {
                // This will fail for CORS requests. We just continue with the
                // fetch caching logic below and do not pass the ID token.
            }

        }
        return fetch( req );
    };
    // Fetch the resource after checking for the ID token.
    // This can also be integrated with existing logic to serve cached files
    // in offline mode.
    event.respondWith( getIdToken().then( requestProcessor, requestProcessor ) );
} );

ТакТаким образом, мой вопрос ... Является ли запасной вариант text(), который я добавляю, когда contentType POST не JSON или FormData собирается охватить все углы, или я должен рассмотреть новый метод передачи тела POST.

1 Ответ

0 голосов
/ 20 февраля 2019

Если вы хотите изменить Request, сохранив body, но с новым или обновленным headers, самый простой подход - передать исходный запрос в качестве первого параметра конструктору Request, которыйтипа RequestInfo;это может быть либо строковый URL, либо существующий объект Request.Любые поля, которые вы указываете во втором параметре, который имеет тип RequestInit, будут переопределять поля в исходном ответе.

Будет немного сложнее, если вы хотите добавить вдополнительное значение заголовка при сохранении всех заголовков из исходного запроса, поскольку по умолчанию, если указать только новые значения в headers, это перезапишет все исходные заголовки.Поэтому вам нужно убедиться, что вы установили headers на комбинацию исходных заголовков и нового заголовка.

Вот код, который иллюстрирует это:

// This request might be created implicitly by the web app,
// but let's just create it manually as an example:
const originalRequest = new Request('https://example.com', {
  body: 'shared body',
  method: 'POST',
  headers: {
    'x-header': 'my header value'
  },
});

// Start with the original headers as a baseline:
const modifiedHeaders = new Headers(originalRequest.headers);
// Make any changes you want:
modifiedHeaders.set('Authorization', 'Bearer 12345');

// Create a new request based on the original,
// with the modified headers:
const modifiedRequest = new Request(originalRequest, {
  headers: modifiedHeaders,
});

// Everything else in modifiedRequest should be as-is,
// but the headers will be updated.
// Do whatever you want with modifiedRequest at this point.

Одна вещь, на которую следует обратить вниманиезаключается в том, что при таком подходе тело исходного запроса будет использоваться при создании измененного запроса.Это не должно иметь значения в вашем случае использования, поскольку только body измененного запроса будет считываться (когда вы передадите его fetch()).Если по какой-то причине вам необходимо прочитать оба body s, то сначала вызовите clone() в исходном запросе, например

const modifiedRequest = new Request(originalRequest.clone(), {...});
// The two requests now have independent bodies.
...