Skip to content
Bloga Dönün
Eğitimler

UTF-8 BOM: JSON ayrıştırma ve CSV hatalarını çözün

UTF-8 BOM, kusursuz görünen bir dosyada JSON.parse'ı bozar. Görünmez EF BB BF baytlarını nasıl bulacağınızı, her dilde nasıl temizleyeceğinizi ve Excel'in bunu ne zaman istediğini öğrenin.

14 dakika okuma

UTF-8 BOM: JSON ayrıştırma ve CSV hatalarını çözün

UTF-8 BOM kaynaklı bir JSON ayrıştırma hatası, göremediğiniz üç bayttan ibarettir. Dosya editörünüzde tertemiz açılır, cat tam beklediğiniz şeyi basar, linter’ınız memnundur ve JSON.parse yine de daha ilk karakterde hata fırlatır.

node v25.8.2 üzerinde ölçüldüğünde hata şöyle görünür:

SyntaxError: Unexpected token '', "{"a":1}" is not valid JSON

Terminaliniz o tırnakların arasına ne çizdiyse, aslında tek bir karakterdir: EF BB BF baytları olarak saklanan U+FEFF. Katı JSON’da bu karaktere ayrılmış bir yer yoktur. Ayrıştırıcı 0. konumda {, [, bir rakam, bir tırnak ya da boşluk bekler; U+FEFF bunların hiçbiri değildir.

Sorunun BOM olduğunu zaten biliyorsanız, kontrol edebildiğiniz tarafı seçin:

Neyi değiştirebiliyorsunuzÇözüm
Node, dosya okurkenJSON.parse(raw.replace(/^/, ''))
Python, dosya okurkenopen(path, encoding='utf-8-sig')
Diskteki dosyanın kendisitail -c +4 data.json > clean.json

Sayfanın geri kalanı, bu üç satırın yetmediği durumlar için: BOM’a benzeyen ama BOM olmayan hatalar, dosyayı her seferinde yeniden BOM’layan kaynaklar ve BOM’u silmenin işleri bozduğu tek biçim. BOM’un ne olduğunu ve yeni bir dosyada bulunması gerekip gerekmediğini UTF-8, UTF-16 ve Unicode kodlama rehberi ele alıyor. Bu sayfa ise sizinkinin çoktan bir şeyi bozmuş olduğunu varsayıyor.

Aşağıdaki bütün ölçümler node v25.8.2 ve Python 3.14.5 üzerinde yapıldı.

1. BOM’u suçlamadan önce hatanızın elediği ihtimaller

  1. konumdaki bir JSON hatasını arayan insanların çoğunda BOM yoktur. Dört farklı sorun aynı biçimde bir mesaj üretir; tırnak içindeki karaktere bakmak dördünü birbirinden ayırmaya yeter. V8’in ürettiği metinler birebir şunlardır:
Hata metniAslında ne olduğuSonraki adım
Unexpected token '', "{"a":1}" is not valid JSON0. baytta UTF-8 BOMBölüm 2
Unexpected token '<', "<!DOCTYPE "... is not valid JSONYanıt HTML’di: bir hata sayfası, bir oturum açma yönlendirmesi, bir proxy uyarısıHam gövdeyi ve durum kodunu loglayın
Unexpected end of JSON inputGövde boştuDurum kodunu ve Content-Length değerini kontrol edin
"undefined" is not valid JSONJSON.parse’a hiç atama yapılmamış bir değişken verdinizÇağıran kodu düzeltin

Kural ezberlenecek kadar kısa. Tek tırnakların içindeki karakteri okuyun. < gördüyseniz elinize HTML geçmiştir. Seçemediğiniz bir kutu, bir boşluk ya da bir soru işareti U+FEFF demektir. Tırnak içinde hiçbir şey yoksa, en baştan girdi hiç yoktu demektir.

Eski ifade ve yeni ifade

json parse unexpected token position 0 aramasının sonuçları çoğunlukla eski bir V8 mesajına göre yazılmıştır:

SyntaxError: Unexpected token in JSON at position 0

O ifade konumu söyleyip karakteri gizliyordu. Bugünkü ifade tam tersini yapıyor: karakteri ve girdiden bir parçayı gösteriyor. Bu çok daha kullanışlı; ama karşınıza çıkan sayfa, sizin kullanmadığınız bir runtime’ı anlatıyor olabilir. Hatanız hâlâ karakter yerine bir konum söylüyorsa daha eski bir motordasınız demektir; aşağıdaki teşhis değişmez.

2. On saniyede BOM olduğunu doğrulayın

Aşağıdaki dört kontrol kabaca hızlarına göre sıralı; herhangi biri meseleyi kapatır.

İlk üç bayta bakın.

$ hexdump -C data.json | head -1
00000000  ef bb bf 7b 22 61 22 3a  31 7d                    |...{"a":1}|

7b ({) baytından önce gelen ef bb bf BOM’dur. Sağdaki ASCII sütununda görünen ..., o üç baytın yazdırılabilir bir karşılığı olmadığı anlamına gelir.

file komutuna sorun. Doğrudan söyler; üstelik dosya türü konusundaki kararını da tamamen değiştirir:

$ file data.json
data.json: Unicode text, UTF-8 (with BOM) text, with no line terminators

$ file clean.json
clean.json: JSON data

Node’da ilk kod noktasına bakın.

const fs = require('fs');
const raw = fs.readFileSync('data.json', 'utf8');
console.log(raw.charCodeAt(0) === 0xFEFF);   // true

Editörün durum çubuğunu okuyun. VS Code sağ alt köşede UTF-8 with BOM yazar ve üzerine tıkladığınızda Save with encoding seçeneğini sunar. Editörünüz durumu baştan beri biliyordu; sadece o küçük etiketten başka hiçbir yerde söylemedi.

Yerelde dökümünü alamadığınız bir şeyin bayt düzeyindeki görünümü için içeriği Base64 Kodla ve Çöz aracına yapıştırın. Bir payload’un başındaki UTF-8 BOM her zaman 77u/ ile başlayan bir karakter dizisine kodlanır; bunu bir log satırında tanıyabilmek işe yarar.

3. BOM’unuz nereden geldi

Bir build adımının her saat yeniden ürettiği bir dosyadan BOM’u silmek, ömrü bir saat olan bir çözümdür. Sık rastlanan üreticiler:

  • Excel’in Farklı Kaydet → CSV UTF-8 seçeneği. Bu bir hata değil, bilinçli bir tercihtir; nedenini 7. bölüm anlatıyor.
  • Not Defteri ve diğer Windows editörleri, UTF-8 with BOM biçimini ayrı bir kaydetme seçeneği olarak sunar, bazen de varsayılan olarak.
  • VS Code, files.encoding ayarı utf8bom olduğunda; bu ayar ister kullanıcı ayarlarınızda dursun, ister kimsenin bakmadığı .vscode/settings.json dosyasına commit’lenmiş olsun.
  • PowerShell’de kabuk yönlendirmesi. Bazı PowerShell sürümlerinde > ve Out-File varsayılan olarak BOM yazar; üstelik varsayılan davranış, yalnızca Windows’ta çalışan 5.x hattı ile çapraz platform 6/7 hattı arasında farklıdır. Bu konuda hafızanıza güvenmeyin: bir dosya yazın ve ilk üç baytını 2. bölümdeki komutlarla kontrol edin.
  • Elle yazılmış dışa aktarma kodu. Bir imza yazılıp yazılmayacağını belirtmeden UTF-8 kodlayıcı kuran her yazıcı, o framework’ün varsayılan olarak seçtiği davranışı devralır. Framework’ler de bu konuda aynı yolu seçmedi. Eski .NET ve eski Java dışa aktarma yolları her zamanki şüphelilerdir.
  • Veritabanı ve BI dışa aktarma araçları; çıktıyı çoğunlukla bir hesap tablosu okuduğu için sık sık BOM ekler.

Dosya bir iş ortağından ya da bir tedarikçiden geliyorsa ve üreticiyi değiştiremiyorsanız 4. bölüme geçip okuma sırasında temizleyin. Kendi deponuzdan geliyorsa kalıcı yanıt 9. bölümde.

4. JavaScript ve Node tarafında çözmek

Kafa karışıklığı asıl burada yoğunlaşıyor, çünkü JavaScript ekosisteminin tek bir BOM politikası yok. Birkaç tane var ve birbirleriyle çelişiyorlar. Aynı dosya, aynı runtime, node v25.8.2 üzerinde ölçüldü:

APIBOM davranışıArdından gelen JSON.parse
fetchres.json()temizlenirbaşarılı olur
fs.readFileSync(f, 'utf8')korunurbaşarısız olur
new TextDecoder() (varsayılan)temizlenirbaşarılı olur
new TextDecoder('utf-8', { ignoreBOM: true })korunurbaşarısız olur
require('./data.json')temizleniryok, zaten ayrıştırılmış
import(..., { with: { type: 'json' } })temizleniryok, zaten ayrıştırılmış

Bu tablodan iki sonuç çıkıyor ve ikisi de sık sık birer öğleden sonraya mal oluyor.

ignoreBOM adının söylediğinin tam tersini yapar

ignoreBOM: true, “BOM’u yok say” demek değildir. “BOM’un özel anlamını yok say ve onu sıradan bir karakter olarak tut” demektir. Onu kaldıran değer, varsayılan olan false’tur. Ad, çözücünün neyi yok saydığını anlatıyor; sizin elinize ne geçeceğini değil. Adı en doğal biçimde okuyup true yazarsanız, silmeye çalıştığınız baytı olduğu gibi koruyan bir çözücü elde edersiniz.

Neden tarayıcıda çalışıp Node’da bozuluyor

Sorunun en çok bildirilen hâli bu: aynı JSON URL’si ön yüz kodunda sorunsuz ayrıştırılırken, bir Node betiği dosyayı diskten okur okumaz hata fırlatıyor. Dosyada değişen hiçbir şey yok. res.json() çözme işini TextDecoder ile aynı mekanizma üzerinden yapar ve yol boyunca BOM’u düşürür; fs.readFileSync(path, 'utf8') ise dosyadaki her karakteri, U+FEFF dahil, olduğu gibi size verir.

Aynı asimetri, require('./config.json') çalışırken JSON.parse(fs.readFileSync('./config.json', 'utf8')) çağrısının neden çalışmadığını da açıklar. Node’un JSON modül yükleyicisi BOM’u temizler; elle yazılan yol temizlemez.

BOM’u temizlemek

const fs = require('fs');
const raw = fs.readFileSync('data.json', 'utf8');
const data = JSON.parse(raw.replace(/^/, ''));

Deseni ^ ile sabitleyin. Sabitlenmemiş genel bir değiştirme, karakter dizisi değerlerinin içindeki meşru U+FEFF karakterlerini de silerdi; bu bir çözüm değil, veri kaybıdır.

Tesadüfen işe yarayan daha sessiz bir alternatif: JSON.parse(raw.trim()) de başarılı olur, çünkü ECMAScript U+FEFF’i boşluk karakteri sayar ve String.prototype.trim onu kaldırır. Bu gerçek bir davranıştır, yukarıda doğrulandı; ama JavaScript şartnamesine özgü bir rastlantıdır ve başka dillere taşınmaz. Python’un str.strip() metodu bir U+FEFF’i bulduğu yerde bırakır.

Temizlenmiş sonucun yalnızca hata fırlatmadığından değil gerçekten geçerli olduğundan da emin olmak isterseniz JSON Biçimlendirici aracına yapıştırın. BOM gittikten sonra 0. konum için geriye kalan adaylar sıradan kaçış sorunlarıdır; bunları JSON dizelerini escape etme rehberi baştan sona ele alıyor.

5. Python tarafında çözmek: utf-8-sig

Sorunu hata mesajında adıyla söyleyen tek runtime Python’dur. BOM ile başlayan bir dosyayı düz UTF-8 olarak açın; json size hem teşhisi hem çözümü tek satırda söyler:

JSONDecodeError: Unexpected UTF-8 BOM (decode using utf-8-sig): line 1 column 1 (char 0)

unexpected utf-8 bom aratıp buraya düştüyseniz, o ifade işte buradan geliyor. İşaret ettiği codec BOM’u bir imza olarak okur ve atar:

import json

with open('data.json', encoding='utf-8-sig') as f:
    data = json.load(f)

utf-8-sig, BOM içermeyen dosyalarda da güvenlidir. Varsa temizler, yoksa düz UTF-8 gibi davranır; bu da onu kendi üretmediğiniz her dosya için doğru varsayılan yapar.

Bayt ile metin farklı davranır

Bu asimetriyi bilmek işe yarar, çünkü hata ara ara ortaya çıkıyormuş gibi görünür:

import json

json.loads(open('data.json', 'rb').read())       # {'a': 1}      çalışır
json.loads(open('data.json', encoding='utf-8').read())  # yukarıdaki hatayı fırlatır

bytes üzerinde çalışan json.loads, önce bir kodlama tespiti adımı yürütür, BOM’u fark eder ve sizin yerinize utf-8-sig ile çözer. Ona zaten çözülmüş bir str verirseniz tespit edilecek bir şey kalmaz, dolayısıyla U+FEFF ayrıştırıcıya kadar ulaşır. İki kod yolu birbirine denk görünüyor; oysa yalnızca biri durumu sessizce hallediyor.

Bilerek BOM yazmak

Aynı codec ters yönde de çalışır; Excel için dosya üretme yolu budur:

with open('report.csv', 'w', encoding='utf-8-sig', newline='') as f:
    f.write('name\n')

O dosya ef bb bf ile başlar. Bunu ne zaman isteyeceğinizi 7. bölüm anlatıyor.

CSV tuzağı

BOM ile başlayan metin üzerinde csv.DictReader, doğru bir CSV ayrıştırıcısının yapması gerekeni tam olarak yapar ve kimsenin eşleştiremeyeceği bir anahtar üretir:

import csv, io

data = 'name,age\nAlice,30\n'
print(list(next(csv.DictReader(io.StringIO(data))).keys()))
# ['name', 'age']

İlk sütununuz name değildir. U+FEFF ve ardından gelen name’dir; her row['name'] araması KeyError fırlatırken başlık, elinizdeki her debugger’da doğru görünür. Dosyayı encoding='utf-8-sig' ile açmak, okuyucu daha görmeden BOM’u kaldırır.

6. Java, Go, PHP ve kabukta BOM’u kaldırmak

Aşağıdakilerin hepsi aynı işi farklı bir katmanda yapıyor: elinizde bayt mı yoksa metin mi olduğuna göre ya üç baytı (EF BB BF) ya da tek bir karakteri (U+FEFF) silersiniz. Dilinizde BOM’u tanıyan bir codec yoksa bunu elle yapın.

Java, BOM’u baştaki bir  karakterine çözer:

String text = Files.readString(path, StandardCharsets.UTF_8);
if (!text.isEmpty() && text.charAt(0) == '') {
    text = text.substring(1);
}

Go, unmarshal işleminden önce bayt düzeyinde çalışarak:

raw, err := os.ReadFile("data.json")
if err != nil {
    return err
}
raw = bytes.TrimPrefix(raw, []byte{0xEF, 0xBB, 0xBF})

var v map[string]any
err = json.Unmarshal(raw, &v)

PHP, bayta sabitlenmiş bir desenle:

$raw  = file_get_contents('data.json');
$raw  = preg_replace('/^\xEF\xBB\xBF/', '', $raw);
$data = json_decode($raw, true);

BOM’u bir değişkenden değil de dosyanın kendisinden kaldırmak isterseniz, aşağıdaki dört komutun hepsi ef bb bf ile başlayan bir dosya üzerinde doğrulandı:

# Yerinde, GNU sed (Linux). Kaçışları sed değil, kabuk açar.
sed -i $'1s/^\xEF\xBB\xBF//' data.json

# Yerinde, BSD sed (macOS)
sed -i '' $'1s/^\xEF\xBB\xBF//' data.json

# Perl'ün bulunduğu her yerde, yerinde. Yalnızca ilk satır.
perl -i -pe 's/^\x{ef}\x{bb}\x{bf}// if $. == 1' data.json

# İlk üç bayt olmadan kopyalar. Yalnızca BOM olduğunu biliyorsanız güvenlidir.
tail -c +4 data.json > clean.json

tail biçimi kaba olanıdır: o üç bayt BOM olsa da olmasa da onları siler. Önce 2. bölümle doğrulayın.

7. CSV istisnası: Excel BOM’un korunmasını ne zaman ister

Yukarıdaki her şey BOM’u bir hasar olarak ele alıyor. Tek bir yerde ise gerçek bir işlevi var; orada silmek çalışan bir dosyayı bozuyor.

csv bom excel aramaları birbirine zıt iki şikâyete ayrılıyor; bu da tek bir kuralın yanlış yönde uygulandığının iyi bir işareti:

  1. “CSV’m Excel’de gerçek karakterler yerine é ve æ¥æ¬èª ile açılıyor.” BOM eksik.
  2. “İlk sütunumun adı name ve betiğim onu bulamıyor.” BOM var.

Excel bunu neden istiyor

Windows’taki Excel’in bir CSV’nin UTF-8 olduğunu anlamasının güvenilir bir yolu yoktur. Ne bir header, ne bir bildirim, ne de bir üst veri vardır: .csv dosyası yalnızca bayttır. Bir sinyal olmadığında sistem yereline geri düşer (ABD ve Batı Avrupa’da Windows-1252, Rusya’da Windows-1251) ve ASCII dışındaki her karakter yanlış çıkar. BOM işte o sinyaldir. Başa üç bayt gelir ve Excel UTF-8’i doğru okur.

CSV’de BOM’un işi işte budur; geriye tek satıra sığan bir karar kalıyor:

Bir makinenin ayrıştırması için yazıldıysa BOM’u temizleyin. Bir insanın Excel’de çift tıklaması için yazıldıysa BOM’u koruyun.

Diğer taraftaki arıza

Aynı dosyayı bir ayrıştırıcıya verin; BOM ilk başlık hücrenizin içine karışır. Node’da:

const header = 'name,age'.split(',');
console.log(JSON.stringify(header));   // ["name","age"]

const row = { 'name': 'Alice', age: 30 };
console.log(row.name);                 // undefined

row.name değeri undefined’dır; oysa anahtar loglarınızda, debugger’ınızda ve console.table çıktınızda name olarak görünür. Arıza biçimi 5. bölümdeki Python KeyError’ıyla birebir aynı. “Alan adı eşleşiyor ama değer yok” tablosunu her gördüğünüzde ilk akla gelecek şüpheli BOM olsun.

Kendi dönüştürücülerimiz bu işin iki tarafını da bilerek ele alıyor. CSV’den JSON’a Dönüştürücü, ayrıştırmadan önce girdinin başındaki BOM’u temizler; böylece doğrudan Excel’den çıkan bir dosya name değil name üretir. Ters yönde ise JSON’dan CSV’ye Dönüştürücü BOM’u açık bir anahtar hâline getirir; Excel hazır ayarı da BOM’u noktalı virgül ayırıcı ve CRLF satır sonlarıyla birlikte etkinleştirir. Avrupa Excel yerellerinin ihtiyaç duyduğu bileşim tam olarak budur. Ayırıcılar, tırnaklama ve tür çıkarımı etrafındaki daha geniş dönüştürme kararları için CSV’den JSON’a dönüştürme rehberi konuyu adım adım anlatıyor.

8. JSON’un ötesinde: BOM başka nerelerde karşınıza çıkar

JSON bu konuda gürültü çıkarır. Diğer biçimler çıkarmaz.

Kabuk betikleri. BOM, dosyanın başı ile #! arasına oturur; bu yüzden çekirdek hiçbir zaman bir shebang görmez ve yorumlayıcınızı hiç çalıştırmaz. macOS’te ölçtüğümüzde kabuk sh’a geri düştü ve shebang satırını var olmayan bir dosya gibi bildirdi:

./bom.sh: line 1: #!/bin/sh: No such file or directory

Betik yine de yanlış yorumlayıcı altında çalıştı; bu, hata verip durmaktan daha kötüdür. Başka sistemler durumu farklı ifade eder, en bilineni bad interpreter hatasıdır. Tamamen doğru bir #!/usr/bin/env python3 satırıyla başlayan bir betik o yolun var olmadığını söylüyorsa baytlara bakın.

PHP. <?php ... ?> dışındaki her şey çıktıdır ve açılış etiketinden önceki bir BOM, kodunuz çalışmadan gönderilen üç baytlık çıktıdır. Ardından ilk header(), session_start() ya da setcookie() çağrısı klasik headers already sent uyarısıyla başarısız olur ve 1. satırı bomboş görünen bir dosyayı işaret eder.

.env dosyaları ve her türlü anahtar değer biçimi. Mekanizma CSV örneğiyle birebir aynı: ilk değişkeniniz DATABASE_URL değildir, U+FEFF ve ardından gelen DATABASE_URL’dir; dolayısıyla arama ıskalarken dosya bir insana doğru görünür. Sonraki bütün değişkenler çalışır ve bu da sorunu tek bir ayara özgüymüş gibi gösterir.

XML ise ters yöndeki istisnadır. XML şartnamesi, kodlama otomatik algılamasının bir parçası olarak bir belgenin başındaki UTF-8 BOM’a açıkça izin verir ve ayrıştırıcıların bununla baş etmesi zorunludur. Python’un xml.etree.ElementTree modülü testlerde BOM ile başlayan bir belgeyi hiç şikâyet etmeden kabul etti. XML tarafında bir şey bozuluyorsa sebebi büyük olasılıkla BOM değildir.

9. Sorunu kaynağında durdurun

Mekanizmayı kavradıktan sonra geriye tek bir iş kalıyor: dosyanın bir daha BOM kapmasını engellemek.

Kodlamayı .editorconfig dosyasında sabitleyin. charset özelliği utf-8 ile utf-8-bom değerlerini birbirinden ayrı kabul eder; bu yüzden istediğinizi yazmak hiçbir belirsizlik bırakmaz:

[*]
charset = utf-8

Bunu geçersiz kılan editör ayarını kontrol edin. VS Code’da bu ayar "files.encoding": "utf8", aranacak değer ise utf8bom. Kullanıcı ayarlarınızın yanı sıra çalışma alanının .vscode/settings.json dosyasına da bakın, çünkü commit’lenmiş bir çalışma alanı ayarı ekipteki herkese sessizce uygulanır.

CI’da ya da bir pre-commit hook’unda tarayın. Aşağıdaki betiğin hiçbir bağımlılığı yok ve bir şey bulduğunda sıfırdan farklı bir kodla çıkıyor:

#!/bin/sh
# İzlenen herhangi bir dosya EF BB BF ile başlıyorsa hata ver
found=0
for f in $(git ls-files '*.json' '*.md' '*.sh'); do
  if [ "$(head -c3 "$f" | od -An -tx1 | tr -d '[:space:]')" = "efbbbf" ]; then
    echo "BOM: $f"
    found=1
  fi
done
exit $found

İki yönde de doğrulandı: BOM ile başlayan bir dosya izlendiğinde sorunlu yolları listeleyip 1 ile çıkıyor, dosyalar temizlendiğinde ise 0 ile çıkıyor.

İzin verilen tek istisnayı yazıya dökün. “Hiçbir yerde BOM yok” kuralı, birinin hesap tablosu dışa aktarımına ihtiyaç duyduğu ilk anda çiğnenir ve ardından tümden yok sayılır. Bunun yerine istisnayı açıkça belirtin: BOM’a yalnızca Excel için üretilen CSV dosyalarında izin verilir, başka hiçbir yerde. Dışa aktarma dizinini tarama betiğinin kapsamı dışında bırakın; kural ancak o zaman günlük kullanımda ayakta kalır.

10. Altmış saniyelik ikiye bölme akışı

Sırayla uygulayın. Her adım ya işi bitirir ya da bir sonraki adıma daha küçük bir sorun devreder.

  1. Konumu değil, karakteri okuyun. 1. bölüm. < HTML demektir ve sizin işiniz burada biter. Tırnak içinde hiçbir şey yoksa gövde boştur. Okunamayan bir kutu görüyorsanız devam edin.
  2. Baytları doğrulayın. hexdump -C file | head -1. İlk üç bayt ef bb bf değilse durun: bu bir BOM değildir ve aşağıdakilerin hiçbiri işinize yaramaz.
  3. Nereden girdiğini bulun. Dosya diskte mi BOM ile başlıyor, yoksa diskte temiz olup kodunuzun eline geçtiğinde mi BOM’lu hâle geliyor? Diskte temiz olan bir dosya, pipeline’ınızdaki bir şeyin BOM eklediği anlamına gelir.
  4. Düzeltmek için tek bir taraf seçin. Üretici bir tedarikçi, bir yükleme ya da sizin sahibi olmadığınız bir build adımıysa okuma sırasında temizleyin. Üretici sizinse üreticiyi düzeltin, çünkü okuma tarafındaki çözümün her okuyucuda yeniden uygulanması gerekir.
  5. Çözümü çözme sınırında uygulayın, daha derinde değil. encoding='utf-8-sig' open() çağrısında dursun; üç fonksiyon sonra bir karakter dizisi üzerinde .lstrip() olarak değil. Sorunu yığının derinlerinde çözmek, dosyayı okuyacak bir sonraki kod yolunun aynı hatayı yeniden keşfetmesi demektir.
  6. Baytların değiştiğini doğrulayın. 2. adımı yeniden çalıştırın. Bir kod yolunda işe yarayan ama dosyaya hiç dokunmamış bir çözüm, bir sonraki yolda başarısız olacaktır.
  7. Tarama betiğini ekleyin. 9. bölüm. Aksi hâlde bütün bunları gelecek çeyrekte yeniden yaparsınız.

SSS

UTF-8 BOM zorunlu mu?

Hayır. UTF-8’in tek bir bayt sırası vardır, dolayısıyla bir işaretin ayırt edeceği bir şey yoktur. Unicode, UTF-8 BOM’una bir kodlama imzası olarak izin verir ama önermez; JSON ise doğrudan yasaklar: RFC 8259, uygulamaların bir JSON metnine bayt sırası işareti eklememesi gerektiğini belirtir.

Dosya editörümde neden düzgün görünüyor ama ayrıştırılamıyor?

Çünkü U+FEFF hiçbir şey olarak görüntülenir. Onu tanıyan editörler karakteri gizler ve bunun yerine durum çubuğunda UTF-8 with BOM yazar. Tanımayanlar ise sıfır piksel çizer. cat, less ve bir kod inceleme diff’i de tıpatıp aynı görünür. Onu yalnızca bayt düzeyindeki bir görünüm açığa çıkarır.

JSON.parse BOM’u hiç kendiliğinden temizler mi?

Asla. JSON.parse bir karakter dizisi alır ve U+FEFF’i nerede görürse görsün beklenmedik bir karakter sayar. Onu temizleyen, bir üstteki katmandır. Bir fetch sonrası res.json(), Node’un .json dosyaları için kullandığı require() ve varsayılan ayarlarıyla TextDecoder; üçü de ayrıştırıcı herhangi bir şey görmeden önce BOM’u kaldırır.

CSV dosyalarından BOM’u kaldırmalı mıyım?

Dosyayı kimin açacağına bağlı. Herhangi bir ayrıştırıcı BOM’u ilk sütun adınızın içine katar; böylece name, name olur ve her arama ıskalar. Orada temizleyin. Windows’taki Excel ise UTF-8’i algılamak için BOM’u kullanır ve BOM olmadan aksanlı karakterlerle CJK karakterlerini bozar; orada koruyun.

BOM ile sıfır genişlikli boşluk aynı şey mi?

Aynı kod noktası, farklı iş. 0. konumdaki U+FEFF bir bayt sırası işaretidir. Bir belgenin başka herhangi bir yerinde ise ZERO WIDTH NO-BREAK SPACE’tir; Unicode bu kullanımı U+2060 WORD JOINER lehine kullanımdan kaldırdı. Eski metinlerde hâlâ bulunur ve U+FEFF’in dosyaların ortasında ortaya çıkmasının nedeni de budur.

BOM, git diff’lerini ve dosya boyutunu etkiler mi?

Diskte üç bayt tutar ve ona dokunan her diff’te gürültülü tek bir satır çıkarır. Git baytları karşılaştırır; bu yüzden bir BOM eklemek ya da kaldırmak, görüntülenen metin birebir aynı olsa bile 1. satırı yeniden yazar. İncelemelerde kimsenin açıklayamadığı o tek satırlık değişiklik genelde buradan çıkar.

Etiketler: utf-8 bom json csv debugging character-encoding