Giriş Giriş Giriş
JavaScript, web geliştirmede en çok yönlü araçlardan biri olarak etkileşimli, kullanıcı dostu formlar için kalır. Formlar genellikle bir web sitesi ile etkileşime girer - kayıt, çek, veri veya geri bildirim için. ancak, uzun veya karmaşık formlar, kullanıcı deneyimini önemli ölçüde artıran iki özelliktir. ve [[Dönemli dolum, çekout, veri gönderme veya geri bildirim veya geri bildirim)
Autofill, bilinen verilerle önceden yapılan alanları tekrarlayan bir türleme azaltır, otomatik olarak kullanıcı girişini yerel veya uzaktan depolamak için otomatik olarak depolamak için otomatik olarak tekrarlayıcı bir şekilde azaltır. Birlikte, tamamlanmayı teşvik eden ve azaltan bir deneyim sunar. Bu makale, hem vanilya JavaScript kullanarak her iki özelliği uygulamanız için, pratik kod örnekleri, kenar durumu işleme ve güvenlik göz önünde bulundurmaktadır.
Çok adımlı bir çek akışı inşa etmek, uzun bir anket veya basit bir iletişim formu oluşturmak, bu teknikleri ustalaştırmak web uygulamalarınızın güvenilirliğini ve kullanılabilirliğini sağlayacaktır.
Autofill ve Auto- Save
[FONT:0)Autofill[[DÜDÜT:1) veya bir kullanıcı profili verilerinin otomatik olarak depolandığı veri alanlarının otomatik popülasyonunu ifade eder (örneğin, bir kullanıcı tarafından otomatik olarak ziyaret edilir.) Örneğin, bir kullanıcı web sitesi, tarayıcı otomatik dolum, yerel sipariş veya teslimat adresi önceden doldurulabilir, tasarruf süresi ve hataları azaltır.
[FONT:0)Auto-save[DÜDÜT:1], bir kullanıcının mevcut form girişinin normal aralıklarla veya belirli tetikleyicilere (örneğin, alan bulanık, sayfa yüksiz) uygulanmasıdır. Bu, tarayıcı kazalarından kaynaklanan veri kaybına karşı koruma sağlar, ağ kesintilerine veya sayfadan uzaktır. Auto-save özellikle uzun süreli içerik için değerlidir.
Tarayıcının yerli otomatik dolum özelliği ortak alanları (isim, e-posta, adresi), tarayıcılar arasında tutar ve özel veri alanları kapsamaz. JavaScript tabanlı otomatik dolum ve otomatik-save size verilerin nasıl depolandığı konusunda tam kontrol verir ve geri dönüşinizle nasıl senkronize edilir.
Uygulamadan Önce Anahtar Tahminleri
Herhangi bir kod yazmadan önce, uygulamanızın sağlam, güvenli ve kullanılabilir olmasını sağlamak için aşağıdaki faktörleri değerlendirin.
Data Storage Strateji
Verilerin hassas ve kalıcı gereksinimlerine dayanan doğru depolama mekanizması seçin:
- [FONT=0] Yerel Yönetim[[[Dönetici: 1)) - Tarayıcı seanslarında devam etmesi gereken hassas olmayan veriler için uygundur. Data hayatta kalır sayfa yeniden yükleri ve tarayıcı yeniden başlar. maksimum depolama genellikle 5-10 MB.
- [[DÜŞÜNÜ:0)Storage[[DÜT:1) - Yerel Yönetime benzer ama sekme veya tarayıcı kapalıyken veri temizlenir. tam bir oturumda hayatta kalmaması gereken geçici veriler için.
- [FONT:0]Kurallar[Döneticiler[Dönler) ve (Döneticiler) ile doğrudan gönderilenler, onları sunucu-ya entegrasyon için uygun hale getirirler. Ancak, 4 KB boyutu sınırı vardır ve bunu alışkanlık olarak ele alırlar.
- [FONT:0]Server-side, AJAX[DÜDÜDÜDÜDÜDÜDÜSÜŞÜNCÜDÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNCÜŞÜNÜŞÜNÜ: 0,0)AJAX-side, AJAX ile devam eden bir son noktaya kadar geri dönüştüğünü, her zaman müşteri-dün senkronizasyonu sağlar.
Kullanıcı Eksi ve Şeffaflık
Veriler depolandığında veya otomatik olarak otomatik olarak depolandığında kullanıcılar, GDPR ve CCPA gibi Gizlilik düzenlemeleri kişisel verileri depolamak için açık bir onay gerektirir. Otomatik ve otomatik doldurma özellikleri hariç kısa bir bildirim veya bir toggle eklemeyi düşünün. asla müşteri-side depolama numaraları veya şifreleri güçlü bir şifreleme ve kullanıcı onayı olmadan hassas veri depolama gibi.
Performans ve Kaynak Kullanımı
Frequent yerel yönetim veya sunucu aramalarına yazılabilir, özellikle düşük güç cihazları üzerinde. oto-save operasyonları için mücadele veya throttling kullanın ve her anahtarstroke tasarruf etmek için. Batch verileri mümkün olduğunda ve en aza indirmek için.
Otomatik doldurmayı JavaScript ile uygulama
Autofill, daha önce dolu bir forma geri döndüğünde veya bir kullanıcı daha önceden doldurulmuş bir şekilde tetiklenebilir. Aşağıdaki modeller en yaygın senaryoları kapsar.
YerelStorage'dan Temel Autofill
Mağaza formu alanı yerel yönetimlerdeki bireysel anahtarlar olarak değer verir, sonra sayfa yükleri geldiğinde onları alın. Bu yaklaşım basit ve küçük sayıda alan için iyi çalışır.
document.addEventListener('DOMContentLoaded', function() {
const fields = [
{ id: 'name', key: 'user_name' },
{ id: 'email', key: 'user_email' },
{ id: 'phone', key: 'user_phone' }
];
fields.forEach(function(field) {
const value = localStorage.getItem(field.key);
if (value) {
const input = document.getElementById(field.id);
if (input) {
input.value = value;
}
}
});
});
Depolama verileri mevcut tutmak için, kullanıcı bir alanı modize ettiğinde yerel yönetimleri güncelleyin:
document.querySelectorAll('.autofill-field').forEach(function(input) {
input.addEventListener('input', function() {
const key = 'user_' + this.id;
localStorage.setItem(key, this.value);
});
});
URL Parametrelerinden Autofill
Bazı durumlarda, bir kullanıcı bir e-posta kampanyasından bir takip linkini tıkladığı gibi sorgu dize parametrelerine dayalı önceden doldurma formlarına ihtiyacınız olabilir.
document.addEventListener('DOMContentLoaded', function() {
const params = new URLSearchParams(window.location.search);
if (params.has('name')) {
document.getElementById('name').value = params.get('name');
}
if (params.has('email')) {
document.getElementById('email').value = params.get('email');
}
});
Her zaman veri URL parametrelerinden enjeksiyon saldırıları veya yanlış giriş önlemek için onaylayın ve doğrulayın.
Bir Server Response Autofill
Gerçekleştirilmiş kullanıcılar için, arka uçlarından profil verilerini getirin ve form dinamik olarak ortaya koyar. Bu, kontrol akışlarında, hesap ayarları sayfalarında ve büyücüleri üstleniyor.
async function loadUserProfile(userId) {
try {
const response = await fetch(`/api/users/${userId}/profile`);
if (!response.ok) throw new Error('Failed to load profile');
const data = await response.json();
document.getElementById('name').value = data.name || '';
document.getElementById('email').value = data.email || '';
document.getElementById('address').value = data.address || '';
} catch (error) {
console.error('Autofill error:', error);
}
}
document.addEventListener('DOMContentLoaded', function() {
const userId = window.app.userId; // set by your auth system
if (userId) {
loadUserProfile(userId);
}
});
Gelişmiş Autofill Teknikleri
Object Storage ile Autofill
Bireysel anahtarları depolamak yerine, tüm form durumunu tek bir JSON nesnesi olarak kurtarın. Bu, depolama operasyonlarının sayısını azaltır ve karmaşık formları geri yüklemek daha kolay hale getirir.
function saveFormState() {
const state = {};
document.querySelectorAll('.autofill-field').forEach(function(input) {
state[input.name] = input.value;
});
localStorage.setItem('formState', JSON.stringify(state));
}
function restoreFormState() {
const saved = localStorage.getItem('formState');
if (!saved) return;
try {
const state = JSON.parse(saved);
Object.keys(state).forEach(function(name) {
const input = document.querySelector(`[name="${name}"]`);
if (input) {
input.value = state[name];
}
});
} catch (e) {
console.warn('Invalid form state data');
}
}
document.addEventListener('DOMContentLoaded', restoreFormState);
Site Türüne Göre Durumlu Autofill
Farklı alan türleri - metin, e-posta, seçin, çekbox, radyo - farklı bir kullanım gerektirir. Güçlü bir otomatik dolum rutini bu varyasyonlar için dikkate almalıdır.
function fillField(field, value) {
if (!field || value == null) return;
const type = field.type || field.tagName.toLowerCase();
switch (type) {
case 'text':
case 'email':
case 'tel':
case 'url':
case 'number':
case 'textarea':
field.value = value;
break;
case 'select-one':
field.value = value;
break;
case 'checkbox':
field.checked = value === true || value === 'true' || value === 'on';
break;
case 'radio':
const radio = document.querySelector(`input[name="${field.name}"][value="${value}"]`);
if (radio) radio.checked = true;
break;
default:
field.value = value;
}
}
Auto- Save Fonksiyonelity
Auto-save, kullanıcının ilerlemesinin beklenmedik bir şekilde kapatılmasını sağlar. Uygulama, verilerin saklandığı ve nerede saklandığınıza bağlıdır.
Interval-Based Auto- Kaydet
En basit yaklaşım, her N saniyenin tüm form durumunu kurtarmak için geçerlidir. Bu, kullanıcıların bölümler arasında duraklayabileceği uzun formlar için etkilidir.
const AUTO_SAVE_INTERVAL = 30000; // 30 seconds
function autoSave() {
const formData = {};
document.querySelectorAll('.auto-save-field').forEach(function(input) {
if (input.type === 'checkbox') {
formData[input.name] = input.checked;
} else if (input.type === 'radio') {
if (input.checked) {
formData[input.name] = input.value;
}
} else {
formData[input.name] = input.value;
}
});
localStorage.setItem('autoSaveData', JSON.stringify(formData));
console.log('Auto-save executed at', new Date().toLocaleTimeString());
}
let autoSaveTimer = setInterval(autoSave, AUTO_SAVE_INTERVAL);
Sayfa yük üzerindeki kaydedilen verileri geri yükleyin:
document.addEventListener('DOMContentLoaded', function() {
const saved = localStorage.getItem('autoSaveData');
if (!saved) return;
try {
const data = JSON.parse(saved);
Object.keys(data).forEach(function(name) {
const input = document.querySelector(`[name="${name}"]`);
if (!input) return;
if (input.type === 'checkbox') {
input.checked = data[name] === true;
} else if (input.type === 'radio') {
const radio = document.querySelector(`input[name="${name}"][value="${data[name]}"]`);
if (radio) radio.checked = true;
} else {
input.value = data[name];
}
});
console.log('Auto-save data restored');
} catch (e) {
console.warn('Could not parse auto-save data');
}
});
Event-Driven Auto- Kaydet
Daha fazla granular kontrolü için, alan bulanık (bir kullanıcı bir alan terk ettiğinde) veya form teslimiyetini azaltır. Bu gereksiz yazıyı azaltır ve genellikle aralık tabanlı tasarruftan daha verimlidir.
document.querySelectorAll('.auto-save-field').forEach(function(input) {
input.addEventListener('blur', function() {
saveField(this.name, this.value);
});
});
function saveField(name, value) {
const data = JSON.parse(localStorage.getItem('autoSaveData') || '{}');
data[name] = value;
localStorage.setItem('autoSaveData', JSON.stringify(data));
}
Sayfada Kaydet
Herhangi bir öngörülemeyen değişiklikleri yakalamak için, kullanıcının sekmeyi kapatdığında veya uzaklaşırken otomatik olarak tasarruf edin.Bu amaçla etkinlik için ESFLT:12 kullanın.
window.addEventListener('beforeunload', function() {
const formData = {};
document.querySelectorAll('.auto-save-field').forEach(function(input) {
if (input.type === 'checkbox') {
formData[input.name] = input.checked;
} else {
formData[input.name] = input.value;
}
});
localStorage.setItem('autoSaveData', JSON.stringify(formData));
});
Not thatFLT:14), modern tarayıcılarda bazı kısıtlamalara sahiptir - özel bir diyalog gösteremezsiniz, ancak yine de yerel yönetimlere senkronize yazabilirsiniz.
Auto- Save with Debouncing and Throttling
Her anahtarstroke'de tasarruf etmek, tasarruf işleminin yalnızca belirli bir süre için yazımdan sonra gerçekleştirildiğini garanti eder. Throttling limitleri tasarruf frekansı maksimum bir oran için limitleri azaltır.
Debounced Auto- Save
Bu model, tasarruf etmeden önce kullanıcının duraklamalarına kadar beklemek istediğiniz metin alanları için idealdir.
function debounce(func, delay) {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func.apply(this, args), delay);
};
}
const saveFormDebounced = debounce(function() {
const formData = {};
document.querySelectorAll('.auto-save-field').forEach(function(input) {
formData[input.name] = input.value;
});
localStorage.setItem('autoSaveData', JSON.stringify(formData));
console.log('Debounced save');
}, 2000); // Wait 2 seconds after the last input
document.querySelectorAll('.auto-save-field').forEach(function(input) {
input.addEventListener('input', saveFormDebounced);
});
Throttled Auto- Kaydet
Throttling, bir kurtarmanın her bir saniyede meydana geldiğini garanti eder, kaç giriş olayının yangına ne kadar karıştığına bakılmaksızın.
function throttle(func, limit) {
let inThrottle = false;
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => { inThrottle = false; }, limit);
}
};
}
const saveFormThrottled = throttle(function() {
const formData = {};
document.querySelectorAll('.auto-save-field').forEach(function(input) {
formData[input.name] = input.value;
});
localStorage.setItem('autoSaveData', JSON.stringify(formData));
console.log('Throttled save');
}, 5000); // Max one save every 5 seconds
document.querySelectorAll('.auto-save-field').forEach(function(input) {
input.addEventListener('input', saveFormThrottled);
});
Kontrol kutusu veya kaydırıcı gibi hızlı etkileşim için metin-heavy alanları ve throttling için iyileştirici seçin.
Farklı Form Field Türlerini Kullanın
Bir üretim hazır otomatik dolum ve otomatik sistem tüm standart HTML form kontrollerini ele almalıdır. Aşağıda kapsamlı bir yaklaşım vardır.
Text Accesss and Textareas
Bunlar basit - mağaza ve restore theİLFLT:17).
Checkboxes ve Radio Düğmeleri
Kontrol kutusu için, 03.30'u bir boolean olarak saklayın. radyo grupları için seçilen düğmeye ait olan “Ücretsiz” düğmesine tıklayın.
const checkedState = {};
document.querySelectorAll('input[type="checkbox"]').forEach(function(cb) {
checkedState[cb.name] = cb.checked;
});
localStorage.setItem('checkboxState', JSON.stringify(checkedState));
// Restore
const savedCheckboxes = JSON.parse(localStorage.getItem('checkboxState') || '{}');
Object.keys(savedCheckboxes).forEach(function(name) {
const cb = document.querySelector(`input[name="${name}"]`);
if (cb) cb.checked = savedCheckboxes[name];
});
(Dropdown) Elements
elements seçilmiş seçeneği, [[ ⁇ D: 00|s.) mülk ile mağazalarını mağazaya seçin. Multi-select, aynı zamanda birden fazla değer izlemesi gerekir.
// Single select
document.querySelector('select[name="country"]').value = savedData.country;
// Multi-select
if (Array.isArray(savedData.interests)) {
const select = document.querySelector('select[name="interests"]');
Array.from(select.options).forEach(function(opt) {
opt.selected = savedData.interests.includes(opt.value);
});
}
File Accesss
Dosya girişi, güvenlik nedenleri için programmatik olarak ayarlanamaz. Bir sayfa yeniden yüklemeden sonra tekrar dosyaları yeniden yapılandırmaları gerektiğini ifade edin. Ancak, dosyayı görüntülemek için dosyayı saklayın.
// Store file name only (value is empty for security)
document.getElementById('resume').addEventListener('change', function() {
if (this.files.length > 0) {
localStorage.setItem('resumeFileName', this.files[0].name);
}
});
// Display stored file name
const fileName = localStorage.getItem('resumeFileName');
if (fileName) {
document.getElementById('resume-label').textContent = 'Previously selected: ' + fileName;
}
Güvenlik ve Gizlilik
Müşteri hizmetleri depolama uygun ama risklerle geliyor. Bu yönergeleri kullanıcılarınızı ve uygulamanızı korumak için takip edin.
Müşteri-Side Storage'da Hassas Veri Asla
Yerel yönetim ve oturumlar aynı kökeninde çalışan herhangi bir senaryoya erişilebilir, onları HTTPS ve uygun kimlik doğrulama ile savunmasız hale getirir. Asla parola, kredi kartı numaraları, sosyal güvenlik numaraları veya diğer hassas kişisel bilgiler için, sunucunun tarafında otomatik olarak kullanın.
Sanitize ve Tüm Giritleri Geçerli
Yerel yönetimlerden veri geri yükleme zaman, URL parametreleri veya sunucu yanıtları, her zaman verileri DOM'ye eklemeden önce doğrular. Bu, XSS enjeksiyonunu önlerse, veri depolanırsa kötü niyetli HTML veya JavaScript içerir.
function sanitizeValue(value) {
if (typeof value !== 'string') return value;
const div = document.createElement('div');
div.textContent = value;
return div.textContent;
}
// Use when setting input values from external sources
emailInput.value = sanitizeValue(storedEmail);
Expire Stored Data
Yerel yönetimde veri, açıkça kaldırılmamış olmadıkça süresiz olarak devam eder. Sabit verilerle popülasyon formlarından kaçınmak için sonsuzluk mantığını uygular.
function saveWithExpiry(key, data, ttlMinutes) {
const item = {
value: data,
expiry: Date.now() + ttlMinutes * 60 * 1000
};
localStorage.setItem(key, JSON.stringify(item));
}
function loadWithExpiry(key) {
const itemStr = localStorage.getItem(key);
if (!itemStr) return null;
try {
const item = JSON.parse(itemStr);
if (Date.now() > item.expiry) {
localStorage.removeItem(key);
return null;
}
return item.value;
} catch {
return null;
}
}
// Example: expire form state after 24 hours
saveWithExpiry('formState', formData, 24 * 60);
Form Submission
Bir form başarıyla gönderildikten sonra, karışık otomatik veriyi karışıklık ve gereksiz depolama kullanımını önlemek için çıkarın.
document.getElementById('myForm').addEventListener('submit', function() {
localStorage.removeItem('autoSaveData');
localStorage.removeItem('formState');
// Remove individual fields as needed
});
Test ve Debugging
Autofill ve auto-save özellikleri, tam zamanlı ve veri bütünlüğüne bağlıdır.Regresyonları erken yakalamak için aşağıdaki test stratejileri uygulayın.
Tarayıcı Geliştirici Araçları
Uygulama sekmesini Chrome DevTools (veya Firefox'ta depolama sekme) yerel yönetim ve oturum açma girişlerini denetlemek için kullanın. Anahtarların yaratıldığını ve beklenen gibi kaldırıldığınız için konsolu izleyin. JSON parsing veya depolama kotası ile ilgili herhangi bir hata için izleyin.
Simulate Edge Cases
Uygulamanızın sağlam olmasını sağlamak için aşağıdaki senaryoları test edin:
- Form kısmen doldurulırken sayfayı yeniden yükleyin - veriler restore edilmelidir.
- Tarayıcı sekmesini kapatın ve yeniden açın - veriler devam etmelidir (yalnızca yerel yönetim).
- DevTools aracılığıyla tarayıcı depolamasını açın - formlar boş devlet lütufla geri çekilmeli.
- Engelli üçüncü taraf kurabiyeleri - oto-saveınızın hala yerel yönetimlerle çalışmasını sağlayın (bu kurabiye ayarları tarafından etkilenmez).
- Formu başarıyla gönderin - depolamak için veri kaldırılmalıdır.
- Başarısız verilere girin (örneğin senaryo etiketleri) – XSS açıklarından emin olun.
Depolama Mantıkı için Birim Testleri
Otomatik-save mantığınızı ayrı bir modüle dönüştürürseniz, Jest veya Mocha gibi bir çerçeve kullanarak birim testleri yaz. Mock yerelStorage gerçek bir tarayıcı ortamında olmadan kurtarma ve geri yükleme davranışını geri yükleme.
// Example test (pseudo-code)
const storageMock = {};
global.localStorage = {
getItem: (key) => storageMock[key] || null,
setItem: (key, value) => { storageMock[key] = value; },
removeItem: (key) => { delete storageMock[key]; }
};
test('saves and restores form state', () => {
saveFormState({ name: 'Alice', email: '[email protected]' });
const restored = restoreFormState();
expect(restored.name).toBe('Alice');
expect(restored.email).toBe('[email protected]');
});
En İyi Uygulamalar ve İpuçları
- [FONT:0) Tüm form durumu için tek bir depolama anahtarı kullanın Alan başına birden fazla anahtar yerine. Bu, karışıklığı azaltır ve atomik olarak geri yüklemenizi sağlar.
- [FONT:0)Her yol JSON.parse ve JSON.stringify in try/catch[DÜT:1) yozlaşmış veya transuncated veri lütufla ele geçirmeli. Bir malform giriş tüm formu bozmamalıdır.
- [FONT:0)Provide görsel geri bildirim[[Dönetici:0) Otomatik olarak meydana geldiğinde, ince bir "Kaynak" göstergesi, bir zaman damgası veya bir çekmark, kullanıcıların ilerlemelerinin korunmasını sağlar.
- [FONT=0] Kullanıcının seçimi[Dönetici: 0 3) Otomatik doldurma veya otomatik devre dışı bırakma. formda veya kullanıcı ayarları sayfasında bir toggle sağlayın.AİLFLT:28) hiçbir zaman kurtarılmamalıdır (örneğin, şifre alanları).
- [FONT=0) Mobil için optimize etmek[Dönetici:0)[FONTT:0) Mobil tarayıcılar daha az depolama ve daha yavaş I/O. Miniread, verileri mümkün olduğunca çok para yüklerinden kaçınır.
- [FONT:0] Tarayıcılar boyunca test[Dönetici:0) - Safari özel modda en kısıtlayıcı yerel yönetim politikasına sahiptir, yaz aylarında bir istisna atlayın.
- [FONT:0) Bir kütüphaneyi kullanarak [Döneticiler için karmaşık formlar için )Formik) veya [[Dönetici|Dönetici|Dönetici|Dönetici|Döneticileri ve geçerlilik desteği vardır.
- [FONT:0) Zihinde erişilebilirlik sağlayın[[Dönetici: 1 ) - otomatik olarak doldurulan alanlar açık olarak tanımlanabilir ve otomatik bildirim ARIA canlı bölgeleri aracılığıyla ekran okuyucularına duyurmalıdır.
- [FONT:0)Monitor depolama kullanımı[[Dönetici:0)[[FONTT:0))[değiştir | kaynağı değiştir] - yerel yönetim bir kontenjana sahip (tipik olarak 5-10 MB). Formunuz birçok alan veya görüntü içeriyorsa (girişte) Bu sınırı aşabilirsiniz.
Sonuç Sonuç Sonuç Sonuç Sonuç Sonuç Sonuç Sonuç
JavaScript ile etkili otomatik doldurma ve otomatik özellikler, kullanıcı deneyimi ve veri bütünlüğünde önemli gelişmeler sağlayan basit bir süreçtir.Storage for maintain, debouncing and throttling for sensitive data, you can build forms that are both appropriate and safe.
Bu makalede kaplanan teknikler - temel alan seviyesinden otomatik dolum, gelişmiş nesne tabanlı otomatik-save sona erme ile - herhangi bir web projesi için sağlam bir temel sağlayın. tarayıcılar arasında iyice test etmeyi unutmayın, kenar vakaları (özel tarama modu ve depolama kotaları dahil), ve her zaman kullanıcı onayı ve veri gizliliğine öncelik verir.
Bu desenler ile, form terk etmeyi, tamamlanma oranlarını azaltabilirsiniz ve her kullanıcı için daha fazla bağışlayıcı deneyimi oluşturabilirsiniz.Daha fazla okuma için, [[Dönetici:0)MDN belgesini yerel yönetimde depolamak için)