Google app-script extraño error CORS debido a la larga solicitud

Así que hago la aplicación usando simple vainilla html y js que está utilizando api llamada a la aplicación web de google app script la pasada marcha, y su estado trabajando bien, ayer algo raro sucede, mi aplicación deja de funcionar y de consola me enteré de que da error CORS. pero cuando empiezo a investigar, creo que es debido al tiempo de espera, así que el caso es así

mi app llamando api(g app script) a través de fetch(GET) api llama a una función(que está tomando aproximadamente 10s) - rendimiento de la función de retorno a la aplicación

y está causando error de CORS, cuando intento abrir el url de API directamente en la nueva pestaña, está funcionando bien, así que por supuesto su problema de script no función/google

pero cuando cambio la rutina del script google para omitir la función, que es así:

mi app llamando api(g app script) a través de fetch(GET) api sólo devuelve un texto a la aplicación (que no es tiempo de carga)

su trabajo bien ahora en mi aplicación

Así que mi conclusión es, cuando google app script ejecuta alguna función que tarda mucho tiempo (en mi caso 10s) devuelve el error CORS cuando lo encuentro, ¿verdad? ¿O perder algo?

Aquí está mi código de gas:

function doGet(e){
      var outp =somefunction();
      return ContentService.createTextOutput(JSON.stringify({'status': outp}))   
  }
}

cuando me cambio en esto, el fetch funciona bien sin error de cors:

function doGet(e){
      return ContentService.createTextOutput(JSON.stringify({'status': 'sometext'}))   
  }
}

editado: heres the complete code of my google app script(sorry for the spaghetti code)

function ambilberkas(prodi,nim,tanggal,tanggalujian,waktu) {
  var templateId="xxxxxxxxxxxxxxxxxxx"
  var folderId="xxxxxxxxxxxxxxxxxxxxxxxx"
  var container=["nama","judul","waktu","ruangan","ketua penguji","penguji utama","pembimbing","sekretaris","tertanggal","nim","nip1","pangkat1","nip2","pangkat2","nip3","pangkat3","nip4","pangkat4","prodi","telp","tanggalujian"]
  
  var inp=[];
  var target=SpreadsheetApp.openById("xxxxxxxxxxxxxxxxxxxxxx").getSheetByName(prodi)
  var lastrow = target.getLastRow();
  var checkData = target.getRange('B2:B' + lastrow).getValues();
  var checkDataFlat = checkData.map(function(row) {return row[0];}); 
  var cekbaris = checkDataFlat.indexOf(nim)+2;
  inp.push(target.getRange('C' + cekbaris).getValue());
  inp.push(target.getRange('D' + cekbaris).getValue());
  inp.push(waktu);
  inp.push(target.getRange('L' + cekbaris).getValue());
  inp.push(target.getRange('F' + cekbaris).getValue());
  inp.push(target.getRange('G' + cekbaris).getValue());
  inp.push(target.getRange('H' + cekbaris).getValue());
  inp.push(target.getRange('I' + cekbaris).getValue());
  inp.push(tanggal);
  inp.push(nim);
  inp.push(target.getRange('N' + cekbaris).getValue());
  inp.push(target.getRange('R' + cekbaris).getValue());
  inp.push(target.getRange('O' + cekbaris).getValue());
  inp.push(target.getRange('S' + cekbaris).getValue());
  inp.push(target.getRange('P' + cekbaris).getValue());
  inp.push(target.getRange('T' + cekbaris).getValue());
  inp.push(target.getRange('Q' + cekbaris).getValue());
  inp.push(target.getRange('U' + cekbaris).getValue());
  inp.push(prodi);

  var target2=SpreadsheetApp.openById("xxxxxxxxxxxxxxxxxxxxxxxx").getSheetByName("DATA PENDAFTARAN")
  var lastrow2 = target2.getLastRow();
  var checkData2 = target2.getRange('B2:B' + lastrow).getValues();
  var checkDataFlat2 = checkData2.map(function(row) {return row[0];}); 
  var cekbaris2 = checkDataFlat2.indexOf(nim)+2;
  inp.push(target2.getRange('H' + cekbaris2).getValue());
  inp.push(tanggalujian);
  
  var files = DriveApp.getFolderById(folderId).getFilesByName('[' + inp[0] + '] ' + inp[2]);
  while (files.hasNext()) {
    files.next().setTrashed(true);
  }
  
  var documentId = DriveApp.getFileById(templateId).makeCopy('[' + inp[0] + '] ' + inp[2],DriveApp.getFolderById(folderId)).getId();
  var op = DocumentApp.openById(documentId)
  var body = op.getBody();
    
  for(var i = 0; i < inp.length; i++){
    body.replaceText('{{' + container[i] +'}}', inp[i])
  }
  
  op.saveAndClose();
  
  docblob = DocumentApp.openById(documentId).getAs('application/pdf');
  /* Add the PDF extension */
  docblob.setName('[' + inp[0] + '] ' + inp[2] + ".pdf");
  var file = DriveApp.createFile(docblob);
  file.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.VIEW);
  return file.getId();
}

function cekstatus(prodi,nim){
  var returndata=[];
    var target=SpreadsheetApp.openById("xxxxxxxxxxxxxxxxx").getSheetByName(prodi)
    var lastrow = target.getLastRow();
    var checkData = target.getRange('B2:B' + lastrow).getValues();
    var checkDataFlat = checkData.map(function(row) {return row[0];}); 
    var cekbaris = checkDataFlat.indexOf(nim)+2;
    if (checkDataFlat.indexOf(nim) == -1) {
      var target2=SpreadsheetApp.openById("xxxxxxx").getSheetByName("DATA PENDAFTARAN")
      var lastrow2 = target2.getLastRow();
      var checkData2 = target2.getRange('B2:B' + lastrow2).getValues();
      var checkDataFlat2 = checkData2.map(function(row) {return row[0];}); 
      if (checkDataFlat2.indexOf(nim) == -1) {
        returndata.push(0);
        returndata.push("Data NIM Tidak Ditemukan, Silahkan Mendaftar");
      } else{
        returndata.push(1);
        returndata.push("Data Sedang Dalam Proses Validasi oleh Staff Akademik");
      }
    } else{
      if(target.getRange('K' + cekbaris).getValue() == "" || target.getRange('J' + cekbaris).getValue() == "" || target.getRange('L' + cekbaris).getValue() == ""){
        returndata.push(2);
        returndata.push("Data Sedang Dalam Proses Validasi oleh Kaprodi");
      } else{
        returndata.push(3);
        returndata.push(target.getRange('F' + cekbaris).getValue());
        returndata.push(target.getRange('G' + cekbaris).getValue());
        returndata.push(target.getRange('H' + cekbaris).getValue());
        returndata.push(target.getRange('I' + cekbaris).getValue());
        returndata.push(target.getRange('J' + cekbaris).getValue());
        returndata.push(target.getRange('K' + cekbaris).getValue());
        returndata.push(target.getRange('L' + cekbaris).getValue());
        returndata.push(target.getRange('C' + cekbaris).getValue());
        returndata.push(target.getRange('D' + cekbaris).getValue());
      }
    }
  return returndata;
}

function doGet(e){
  if(typeof e !== 'undefined'){
    if(e.parameter.mode == "cekstatus"){
      var hasil=cekstatus(e.parameter.prodi,e.parameter.nim); 
      return ContentService.createTextOutput(JSON.stringify({'status': hasil}))
      setMimeType(ContentService.MimeType.JSON);
    }
    else if(e.parameter.mode == "ambilberkas"){
      var hasil = ambilberkas(e.parameter.prodi,e.parameter.nim,e.parameter.tanggal,e.parameter.tanggalujian,e.parameter.waktu);
      return ContentService.createTextOutput(JSON.stringify({'download disini': 'https://drive.google.com/uc?export=download&id=' + hasil}))
      //return ContentService.createTextOutput('{"status":"1XydIGw3Nin8O_aoTBLCs3Ei-AENnRhLU"}')
      setMimeType(ContentService.MimeType.JSON);
    }    
  }
}

y aquí está mi código de defectos en la aplicación web:

return fetch('first request to the api URL(another function)')
    .then(response => response.json())
    .then(data => {
            Swal.insertQueueStep({
                preConfirm: () => {
                    * return fetch('second request to the api URL(ambilberkas)')
                        .then(data => {
                            //do something
                        })
                }
            })
        })

Pregunta hecha hace 3 años, 4 meses, 28 días - Por javajedi


3 Respuestas:

  • ah, así que su error, depuro mi código y descubrí que esta línea está causando el error:

    var op = DocumentApp.openById(documentId)
    

    hay otro hilo discutiendo esto: openbyid bug

    y la solución alternativa actual es usando el tiempo de ejecución v8.

    Respondida el Dec 18, 2020 a las 00:33 - por codecraftsman

    Votos positivos: 0 | Votos negativos: 0

  • El problema que estás experimentando con CORS (Cross-Origin Resource Sharing) puede estar relacionado con el tiempo de respuesta del servidor. Cuando una solicitud tarda mucho en procesarse, algunos navegadores pueden cancelar la solicitud debido a restricciones de CORS.

    Una forma de evitar este problema es optimizar el tiempo de respuesta de tu función en Google Apps Script. Aquí hay algunas sugerencias:

    • Optimizar el código: Revisa tu código para identificar posibles áreas que puedan estar ralentizando la ejecución. Asegúrate de que estás realizando operaciones de manera eficiente y sin procesos innecesariamente largos.
    • Dividir la tarea en varias solicitudes: Si la función en Google Apps Script tarda mucho tiempo en completarse, considera dividir la tarea en varias solicitudes más pequeñas y asíncronas. Esto podría ayudar a mantener la comunicación con el servidor sin exceder el límite de tiempo de espera de CORS.
    • Implementar Web Workers: Si es posible, considera utilizar Web Workers en tu aplicación web para procesar tareas largas en segundo plano de manera asíncrona. Esto puede ayudar a evitar problemas de tiempo de espera en la solicitud principal.

    También es importante asegurarse de tener configurada correctamente la respuesta de CORS en tu script de Google Apps Script. Puedes agregar el encabezado Access-Control-Allow-Origin al objeto ContentService para permitir solicitudes desde tu dominio. Por ejemplo:

    javascript
    return ContentService
      .createTextOutput(JSON.stringify({'status': outp}))
      .setMimeType(ContentService.MimeType.JSON)
      .addHeader('Access-Control-Allow-Origin', 'https://tudominio.com');
    

    Además, verifica que el método setMimeType en tu función doGet esté siendo llamado de manera correcta y actualizar la respuesta del servidor con el encabezado de CORS:

    javascript
    if (e.parameter.mode == "cekstatus") {
      var hasil = cekstatus(e.parameter.prodi, e.parameter.nim);
      return ContentService.createTextOutput(JSON.stringify({'status': hasil}))
        .setMimeType(ContentService.MimeType.JSON)
        .addHeader('Access-Control-Allow-Origin', 'https://tudominio.com');
    }
    

    Implementar estas mejoras debería ayudarte a evitar el error de CORS debido a tiempos de respuesta largos en tus solicitudes a Google Apps Script.

    Respondida el Dec 19, 2020 a las 00:32 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • El problema que describes es probablemente causado por el tiempo de espera de la llamada fetch. Las llamadas fetch tienen un tiempo de espera predeterminado de 10 segundos, y si la función en el script de Google Apps tarda más de 10 segundos en ejecutarse, la llamada fetch fallará con un error CORS.

    Para resolver este problema, puedes aumentar el tiempo de espera de la llamada fetch utilizando el método setTimeout. Aquí tienes un ejemplo:

    javascript
    fetch('first request to the api URL(another function)', {
      timeout: 20000 // Aumenta el tiempo de espera a 20 segundos
    })
        .then(response => response.json())
        .then(data => {
                Swal.insertQueueStep({
                    preConfirm: () => {
                           
    • return fetch('second request to the api URL(ambilberkas)')
    .then(data => { //do something }) } }) })

    También puedes intentar optimizar la función ambilberkas en el script de Google Apps para que se ejecute más rápido. Esto reducirá el tiempo de espera necesario para la llamada fetch.

    Otra opción es utilizar una biblioteca de terceros como axios para realizar las llamadas fetch. Axios tiene su propio sistema de administración de tiempo de espera, que puede ser más confiable que el tiempo de espera predeterminado del navegador.

    Finalmente, también puedes intentar implementar la paginación en tu código para que las llamadas fetch individuales sean más pequeñas y tarden menos tiempo en ejecutarse.

    Respondida el Dec 19, 2020 a las 00:40 - por Gemini

    Votos positivos: 0 | Votos negativos: 0