본문 바로가기

워크

sessionStorage localStorage

웹에서 상태를 저장할 때 클라이언트(브라우저)에서는 보통 3가지의 방법이 있다.

1. 전통적인 쿠키 (도메인당 쿠키 수 제한, 용량 제한 4KB)

2. HTML5 브라우저 세션 sessionStorage(5MB 제한, 브라우저를 닫으면 지워짐)

3. HTML5 브라우저 스토리지 localStorage (5MB 제한, 따로 지우지 않는 한 계속 유지됨)

쿠키의 경우 서버측 코드로 접근이 가능하지만 2,3번은 불가능하며 별도의 작업(Header, Parameter)에 담아서 서버 측에 전송 가능하다. (쿠키는 매번 서버로 전송 된다 => 네트워크 트레픽 비용 증가)

모던한 웹 개발에선 2,3 번을 주로 권장한다.

 

localStorage  sessionStorage는 다음과 같은 차이점이 있습니다.

  • localStorage는 사용자 브라우저로 범위가 지정됩니다. 사용자가 페이지를 다시 로드하거나 브라우저를 닫았다가 다시 열면 상태가 유지됩니다. 사용자가 여러 개의 브라우저 탭을 여는 경우 탭 간에 상태가 공유됩니다. 명시적으로 지울 때까지 데이터가 localStorage에 유지됩니다.
  • sessionStorage는 사용자의 브라우저 탭으로 범위가 지정됩니다. 사용자가 탭을 다시 로드하면 상태가 유지됩니다. 사용자가 탭 또는 브라우저를 닫으면 상태가 손실됩니다. 사용자가 여러 개의 브라우저 탭을 여는 경우 각 탭에 독립적인 고유한 버전의 데이터가 있습니다.

일반적으로 sessionStorage를 사용하는 것이 더 안전합니다. sessionStorage를 사용하면 사용자가 여러 탭을 열 때 다음과 같은 경우가 발생하는 위험을 방지할 수 있습니다.

  • 탭 간에 상태 스토리지의 버그
  • 한 탭에서 다른 탭의 상태를 덮어쓸 때 혼동되는 동작

앱이 브라우저를 닫았다가 다시 열 때 상태를 유지해야 하는 경우 localStorage를 선택하는 것이 좋습니다.

브라우저 스토리지를 사용하는 경우의 주의 사항:

  • 서버 쪽 데이터베이스를 사용하는 경우와 유사하게, 데이터 로드 및 저장은 비동기입니다.
  • 서버 쪽 데이터베이스와 달리, 미리 렌더링 단계에서는 요청한 페이지가 브라우저에 없기 때문에 미리 렌더링하는 동안 스토리지를 사용할 수 없습니다.
  • Blazor Server 앱의 경우 몇 킬로바이트의 데이터 스토리지를 유지하는 것이 좋습니다. 몇 킬로바이트를 넘을 경우, 네트워크를 통해 데이터를 로드하고 저장하기 때문에 성능에 미치는 영향을 고려해야 합니다.
  • 사용자가 데이터를 보거나 조작할 수 있습니다. ASP.NET Core 데이터 보호는 위험을 완화할 수 있습니다.
public async Task InitAsync()
{
    _initializing = true;
    var vmJson = await _client.GetStringAsync(_config.Url);
    var vm = JsonSerializer.Deserialize<HealthModel>(vmJson, _options);
    _model.AgeYears = vm.AgeYears;
    _model.HeightInches = vm.HeightInches;
    _model.IsFemale = vm.IsFemale;
    _model.IsMetric = vm.IsMetric;
    _model.WeightPounds = vm.WeightPounds;
    _initializing = false;
}

private async void Model_PropertyChanged(object sender, 
    System.ComponentModel.PropertyChangedEventArgs e)
{
    if (_initializing || _config == null)
    {
        return;
    }
    var vm = JsonSerializer.Serialize(_model);
    var content = new StringContent(vm);
    content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
    await _client.PostAsync(_config.Url, content);
}
@page "/LocalStorage"
@inject NavigationManager NavigationManager
@inject Blazored.LocalStorage.ILocalStorageService localStore
@inject Blazored.SessionStorage.ISessionStorageService sessionStorage
@using Blazor.App.Tmp.Data

@using Models.Shared.Blazor
@using Models.Shared.Blazor.Validator
@inject WeatherForecastService ForecastService

<h1>Your Local Session Storage Note</h1>
<MatH3>@getLocalStorage</MatH3>
<MatH3>@getSessionStorage</MatH3>
<textarea @bind="getLocalStorage" />
<textarea @bind="getSessionStorage" />
<br />
<button @onclick="UpdateLocalStorage">Save</button>
<button @onclick="ClearLocalStorage">Clear</button>

@code {
    const string noteKey = "note";
    const string listKey = "lotto";
    public string getLocalStorage { get; set; }
    public string getSessionStorage { get; set; }
    public DtoList getdtLocalStorage { get; set; }
    public DtoList getdtSessionStorage { get; set; }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await SetessionStorage();

            getLocalStorage = await localStore.GetItemAsync<string>(noteKey);
            getSessionStorage = await sessionStorage.GetItemAsync<string>(noteKey);
        }
    }

    private async Task SetessionStorage()
    {
        //await localStore.SetItemAsync(noteKey, "localStore");
        //await sessionStorage.SetItemAsync(noteKey, "sessionStorage");

        ClearLocalStorage();
        await GetLocalSessionStorage();

        //await localStore.GetItemAsync<string>(noteKey);
        //await sessionStorage.GetItemAsync<string>(noteKey);

        //await localStore.SetItemAsync(listKey, dtoList);
        //await sessionStorage.SetItemAsync(listKey, dtoList);
    }

    private async Task GetLocalSessionStorage()
    {
        DtoList dtoList = await ForecastService.GetCustomers(1, 200);

        foreach(var c in dtoList.Dto)
        {
            await localStore.SetItemAsync(string.Format("{0}_{1}", c.Id, c.Name), c.Region.ToString());
            await sessionStorage.SetItemAsync(string.Format("{0}_{1}", c.Id, c.Name), c.Region.ToString());
        }
        foreach (var c in dtoList.Dto)
        {
            await localStore.SetItemAsync(string.Format("{0}_{1}_01", c.Id, c.Name), c.Region.ToString());
            await sessionStorage.SetItemAsync(string.Format("{0}_{1}_01", c.Id, c.Name), c.Region.ToString());
        }
        foreach (var c in dtoList.Dto)
        {
            await localStore.SetItemAsync(string.Format("{0}_{1}_02", c.Id, c.Name), c.Region.ToString());
            await sessionStorage.SetItemAsync(string.Format("{0}_{1}_02", c.Id, c.Name), c.Region.ToString());
        }
        foreach (var c in dtoList.Dto)
        {
            await localStore.SetItemAsync(string.Format("{0}_{1}_03", c.Id, c.Name), c.Region.ToString());
            await sessionStorage.SetItemAsync(string.Format("{0}_{1}_03", c.Id, c.Name), c.Region.ToString());
        }
        foreach (var c in dtoList.Dto)
        {
            await localStore.SetItemAsync(string.Format("{0}_{1}_04", c.Id, c.Name), c.Region.ToString());
            await sessionStorage.SetItemAsync(string.Format("{0}_{1}_04", c.Id, c.Name), c.Region.ToString());
        }
        foreach (var c in dtoList.Dto)
        {
            await localStore.SetItemAsync(string.Format("{0}_{1}_05", c.Id, c.Name), c.Region.ToString());
            await sessionStorage.SetItemAsync(string.Format("{0}_{1}_05", c.Id, c.Name), c.Region.ToString());
        }
        foreach (var c in dtoList.Dto)
        {
            await localStore.SetItemAsync(string.Format("{0}_{1}_06", c.Id, c.Name), c.Region.ToString());
            await sessionStorage.SetItemAsync(string.Format("{0}_{1}_06", c.Id, c.Name), c.Region.ToString());
        }
        foreach (var c in dtoList.Dto)
        {
            await localStore.SetItemAsync(string.Format("{0}_{1}_07", c.Id, c.Name), c.Region.ToString());
            await sessionStorage.SetItemAsync(string.Format("{0}_{1}_07", c.Id, c.Name), c.Region.ToString());
        }
    }

    private async Task GetSessionStorage()
    {
        getdtLocalStorage = await localStore.GetItemAsync<DtoList>(listKey);
        getdtSessionStorage = await sessionStorage.GetItemAsync<DtoList>(listKey);
    }

    public async void UpdateLocalStorage()
    {
        await localStore.SetItemAsync(noteKey, getLocalStorage);
        await sessionStorage.SetItemAsync(noteKey, getSessionStorage);
    }

    public async void ClearLocalStorage()
    {
        //getdtLocalStorage = null;
        await localStore.ClearAsync();
        await sessionStorage.ClearAsync();

        //getdtSessionStorage = null;
        //await localStore.RemoveItemAsync(noteKey);
        //await sessionStorage.RemoveItemAsync(noteKey);
    }
}

'워크' 카테고리의 다른 글

UserAgent 가져오기  (0) 2020.07.17
blazor Cookie  (0) 2020.07.15
blazor MatTab  (0) 2020.07.13
NavigationManager 시트  (0) 2020.07.12
BlazorInputFile FileUpload  (0) 2020.07.11