亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

文本解碼器.prototype.ignoreBOM 未按預期工作

文本解碼器.prototype.ignoreBOM 未按預期工作

手掌心 2022-09-29 17:26:44
我正在使用獲取API來提取csv數據并嘗試創建一個csv文件。但是,我看到前兩個字符是BOM字符。?t然而,我在解碼期間設置,但它不起作用,我總是在CSV的開頭看到ignoreBOM: true?t下面是我的代碼    const fetchData = await newPage.evaluate(async () => {      let url = $('.csvLink').attr('href');      console.log(`in here is the ${url}`);      const stream = await fetch(url);      let reader = stream.body.getReader();      let receivedLength = 0;      while(true) {        const {done, value} = await reader.read();        if (done) {          break;        }        receivedLength += value.length;        let v = new TextDecoder("ISO-8859-1", {fatal: false, ignoreBOM: false}).decode(value, {stream: true});        await window.writeToStream(v, false);      }任何幫助解決這個問題都會很棒。謝謝。
查看完整描述

1 回答

?
月關寶盒

TA貢獻1772條經驗 獲得超5個贊

ignoreBOM 僅適用于 UTF-8 UTF-16BE 和 UTF-16LE 編碼。

如果您在文件的開頭有一個 BOM,那么它可能沒有被編碼為 CP-1252,而是編碼為 UTF,如果該 BOM 在 CP-1252 中讀取,那么它甚至可能是 UTF-16LE:?t

const littleEnd_BOM = new Uint8Array( [ 0xFF, 0xFE ] );

const as_CP1252 = new TextDecoder( 'iso-8859-1' ).decode( littleEnd_BOM );


console.log( as_CP1252 );

因此,代碼中的第一個錯誤是您不想將文本解碼器初始化為CP-1252,而是初始化為UTF-16LE。


現在,對于您確實設置了哪個值存在一些混淆,在您編寫的某一點上將其設置為 ,而在代碼段中將其設置為(默認值)。ignoreBOMtruefalse


如果希望 BOM 表保留在輸出中,請將其設置為 。解析器將忽略該 BOM 標記,這意味著它將將其視為正常字符序列。true


另一方面,如果您希望將其從輸出中刪除,則將其保留為 ,解析器將對其進行特殊處理,并將其從輸出中刪除。false


請注意,即使 BOM 位于此處,它也可能不是從 DOM 字符串打印的:


const UTF16LE_text = new Uint16Array(

      [ ..."\ufeffhello" ].map( (char) => char.charCodeAt(0) )

  );

// to check we really wrote a LE-BOM "FFFE"

const BOM = [ ...new Uint8Array( UTF16LE_text.buffer ).slice( 0, 2 ) ]

  .map( (v) => v.toString( 16 ) ).join('');

console.log( 'BOM:', BOM );


const ignoring_decoder = new TextDecoder( 'UTF-16LE', { ignoreBOM: true } );

const ignored = ignoring_decoder.decode( UTF16LE_text );

console.log( 'ignoreBOM:true  - text:', ignored );

console.log( 'ignoreBOM:true  - char at 0:', ignored.charCodeAt( 0 ) );


const removing_decoder = new TextDecoder( 'UTF-16LE' );

const removed = removing_decoder.decode( UTF16LE_text );

console.log( 'ignoreBOM:false - text:', removed );

console.log( 'ignoreBOM:false - char at 0:', removed.charCodeAt( 0 ) );

但是,您可能面臨的另一個問題是,您正在讀取提取的文本塊,即隨機大小的數據塊。

文本不能以這種方式處理,您需要從明確定義的字節位置解析它才能正確解析它。


幸運的是,該方法有一個選項。使用它,解碼器應該能夠正確讀取流,但要使此選項起作用,您需要將TextDecoder存儲在 while 循環之外,以便它可以將以前的緩沖區保留在內存中。streamTextDecoder.decode()


const fetchData = await newPage.evaluate(async () => {

  let url = $('.csvLink').attr('href');

  const stream = await fetch(url);

  let reader = stream.body.getReader();

  let receivedLength = 0;

  // declare the decoder outside of the loop

  const decoder = new TextDecoder("UTF-16LE");

  while(true) {

    const {done, value} = await reader.read();

    receivedLength += value.length;

    // always use the same decoder

    const v = decoder.decode(value, {stream: true});

    await window.writeToStream(v, false);

    if (done) { 

      break;

    }

  }

}


查看完整回答
反對 回復 2022-09-29
  • 1 回答
  • 0 關注
  • 130 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號