Belajar Capacitorjs - Networking: CapacitorHttp & CORS
Episode 10 of 28

Belajar Capacitorjs - Networking: CapacitorHttp & CORS

Memahami masalah CORS di WebView, solusi CapacitorHttp yang mem-patch fetch/XHR ke native HTTP stack, cookie management, JSON handling otomatis, serta konsumsi API third-party tanpa server proxy.

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Setelah di episode 9 kita menguasai Deep Links dan App State, pada episode ini kita membahas networking di Capacitor — topik yang sering menjadi sumber frustrasi bagi web developer yang pindah ke mobile. CORS yang tidak bisa di-disable, cookie yang tidak work, dan API yang tidak bisa diakses dari WebView adalah masalah umum.

Mengapa networking penting? Karena hampir semua aplikasi mobile membutuhkan API. Jika networking tidak berjalan lancar, aplikasi tidak akan bisa menampilkan data, mengirim form, atau berkomunikasi dengan server.

Masalah CORS di WebView

Di browser, CORS (Cross-Origin Resource Sharing) dikontrol oleh server — browser menolak response yang tidak punya header Access-Control-Allow-Origin. Di WebView, masalahnya lebih kompleks: tidak ada cara untuk "disable" CORS seperti di browser dev tools.

Ketika aplikasi web berjalan di WebView, request dari http://localhost ke https://api.example.com akan diblokir oleh CORS jika server tidak mengizinkan origin tersebut.

Solusi: CapacitorHttp

Capacitor 6+ memperkenalkan CapacitorHttp — fitur yang mem-patch global fetch dan XMLHttpRequest agar menggunakan native HTTP stack (NSURLSession di iOS, HttpURLConnection di Android) alih-alih WebView HTTP engine.

Artinya: CORS tidak berlaku karena request tidak lagi keluar dari WebView, melainkan dari kode native langsung.

Aktifkan CapacitorHttp

capacitor.config.ts dengan CapacitorHttp
const config: CapacitorConfig = {
  // ...
  plugins: {
    CapacitorHttp: {
      enabled: true,  // aktifkan patch global
    },
  },
};

Setelah diaktifkan, semua fetch() dan XMLHttpRequest secara otomatis menggunakan native HTTP stack.

Tanpa Server Proxy

Sebelum CapacitorHttp, banyak developer menggunakan Express proxy atau CORS proxy di server. Dengan CapacitorHttp, kalian bisa langsung mengkonsumsi API:

Fetch API tanpa proxy
// Sebelum CapacitorHttp: perlu proxy server
// const response = await fetch('/api-proxy/external-api.com/data');
 
// Sesudah CapacitorHttp: langsung fetch
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
Kirim cookie manual
const response = await fetch('https://api.example.com/protected', {
  credentials: 'include',
  headers: {
    Cookie: 'session=abc123; theme=dark',
  },
});
Baca cookie dari response
const response = await fetch('https://api.example.com/login', {
  method: 'POST',
  body: JSON.stringify({ username: 'user', password: 'pass' }),
});
 
const setCookie = response.headers.get('Set-Cookie');
console.log('Set-Cookie:', setCookie);

Note

Dengan CapacitorHttp, cookie handling berjalan persis seperti di browser — termasuk cookie persisten dan SameSite attributes. Tidak perlu penanganan khusus.

JSON Handling Otomatis

CapacitorHttp otomatis mengenali Content-Type: application/json dan melakukan parse/stringify:

JSON otomatis dengan CapacitorHttp
// Request JSON
const response = await fetch('https://api.example.com/data', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ query: 'test' }),
});
 
// Response otomatis ter-parse jika content-type JSON
const data = await response.json();

Streaming Limitation

Karena request berjalan di native HTTP stack, ada beberapa limitasi dibanding browser HTTP:

  • Streaming response (ReadableStream) tidak didukung penuh. Response dimuat ke memory sebelum dikembalikan ke JavaScript.
  • Request timeout default lebih panjang dari browser.
  • Redirect handling berbeda sedikit dari browser behavior.

Untuk kebanyakan use case, ini bukan masalah. Streaming hanya diperlukan untuk file besar atau real-time data — yang bisa ditangani dengan WebSocket atau plugin native khusus.

Error Handling

Error handling networking
async function fetchWithRetry(url: string, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      const response = await fetch(url);
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }
      return await response.json();
    } catch (error) {
      console.error(`Attempt ${i + 1} failed:`, error);
      if (i === retries - 1) throw error;
      // Tunggu sebelum retry
      await new Promise(r => setTimeout(r, 1000 * (i + 1)));
    }
  }
}

Kapabilitas Native untuk Request Kompleks

Karena request berjalan di native HTTP stack, kalian mendapatkan beberapa keunggulan:

  • SSL/TLS dikelola oleh sistem operasi, bukan WebView.
  • Certificate pinning bisa ditambahkan di level native (episode 22).
  • Background fetch tersedia untuk update data saat app di background.
  • Upload file mendukung multipart/form-data dengan progress callback.

Tip

Untuk file besar (video, gambar high-res), pertimbangkan upload langsung ke cloud storage (S3, GCS) dengan pre-signed URL. CapacitorHttp sangat cocok untuk ini karena tidak ada batasan CORS.

Penutup

Pada episode 10 ini, kalian telah memahami:

  • CORS tidak bisa di-disable di WebView — tetapi CapacitorHttp menyelesaikannya.
  • CapacitorHttp mem-patch fetch dan XMLHttpRequest ke native HTTP stack.
  • Cookie management, JSON handling, dan error handling berjalan natural.
  • Untuk request kompleks (upload, SSL pinning), native HTTP stack memberikan keunggulan.

Di episode 11 selanjutnya, kita akan membahas Splash Screen, Status Bar, dan Keyboard — polish launch experience, styling status bar untuk dark mode, safe area insets, dan edge-to-edge layout. Sampai jumpa!