How to pass a JSON array as a parameter in URL

前端 未结 9 1227
一整个雨季
一整个雨季 2020-11-28 10:35

I have an requirement to pass a some values from mobile to server in a web service call and so I am planning to pass all the values in JSON format like the below

<         


        
9条回答
  •  独厮守ぢ
    2020-11-28 10:54

    I encountered the same need and make a universal solution (node+browser) that works with the Next.js framework, for instance.

    It even works with circular dependencies (thanks to json-stringify-safe).

    Although, I also built a serializer on top of it to remove unnecessary data (because it's not recommended to use a url longer than 2k chars, see What is the maximum length of a URL in different browsers?)

    import StringifySafe from 'json-stringify-safe';
    
    export const encodeQueryParameter = (data: object): string => {
      return encodeURIComponent(StringifySafe(data)); // Use StringifySafe to avoid crash on circular dependencies
    };
    
    export const decodeQueryParameter = (query: string): object => {
      return JSON.parse(decodeURIComponent(query));
    };
    

    And the unit tests (jest):

    import { decodeQueryParameter, encodeQueryParameter } from './url';
    
    export const data = {
      'organisation': {
        'logo': {
          'id': 'ck2xjm2oj9lr60b32c6l465vx',
          'linkUrl': null,
          'linkTarget': '_blank',
          'classes': null,
          'style': null,
          'defaultTransformations': { 'width': 200, 'height': 200, '__typename': 'AssetTransformations' },
          'mimeType': 'image/png',
          '__typename': 'Asset',
        },
        'theme': {
          'primaryColor': '#1134e6',
          'primaryAltColor': '#203a51',
          'secondaryColor': 'white',
          'font': 'neuzeit-grotesk',
          '__typename': 'Theme',
          'primaryColorG1': '#ffffff',
        },
      },
    };
    export const encodedData = '%7B%22organisation%22%3A%7B%22logo%22%3A%7B%22id%22%3A%22ck2xjm2oj9lr60b32c6l465vx%22%2C%22linkUrl%22%3Anull%2C%22linkTarget%22%3A%22_blank%22%2C%22classes%22%3Anull%2C%22style%22%3Anull%2C%22defaultTransformations%22%3A%7B%22width%22%3A200%2C%22height%22%3A200%2C%22__typename%22%3A%22AssetTransformations%22%7D%2C%22mimeType%22%3A%22image%2Fpng%22%2C%22__typename%22%3A%22Asset%22%7D%2C%22theme%22%3A%7B%22primaryColor%22%3A%22%231134e6%22%2C%22primaryAltColor%22%3A%22%23203a51%22%2C%22secondaryColor%22%3A%22white%22%2C%22font%22%3A%22neuzeit-grotesk%22%2C%22__typename%22%3A%22Theme%22%2C%22primaryColorG1%22%3A%22%23ffffff%22%7D%7D%7D';
    
    describe(`utils/url.ts`, () => {
      describe(`encodeQueryParameter`, () => {
        test(`should encode a JS object into a url-compatible string`, async () => {
          expect(encodeQueryParameter(data)).toEqual(encodedData);
        });
      });
    
      describe(`decodeQueryParameter`, () => {
        test(`should decode a url-compatible string into a JS object`, async () => {
          expect(decodeQueryParameter(encodedData)).toEqual(data);
        });
      });
    
      describe(`encodeQueryParameter <> decodeQueryParameter <> encodeQueryParameter`, () => {
        test(`should encode and decode multiple times without altering data`, async () => {
          const _decodedData: object = decodeQueryParameter(encodedData);
          expect(_decodedData).toEqual(data);
    
          const _encodedData: string = encodeQueryParameter(_decodedData);
          expect(_encodedData).toEqual(encodedData);
    
          const _decodedDataAgain: object = decodeQueryParameter(_encodedData);
          expect(_decodedDataAgain).toEqual(data);
        });
      });
    });
    

提交回复
热议问题