Как настроить WebView в Capacitor для отправки заголовка Referer на iOS?

Я разрабатываю приложение на основе <a href="https://capacitorjs.com/" rel="nofollow">Capacitor</a>, и столкнулся с проблемой на экране с Яндекс.Картами. Этот экран должен быть интегрирован в основное приложение, без создания отдельного нативного экрана. 

В веб-версии и сборке для Android всё функционирует корректно, однако на iOS это не так. Проблема заключается в том, что API Яндекса требует наличия заголовка host в запросе для проверки привязки ключа. WebView на Android и в браузере отправляют этот заголовок, в то время как WebView на iOS — нет. Он отправляет его только для запросов к "внешним" страницам, например, к live-dev серверу типа <a href="http://192.168.xn--u1a.xn--u1a:3000" rel="nofollow">http://192.168.х.х:3000</a>, но не для внутренних ресурсов, таких как <a>capacitor://localhost</a>. 

Дополнительный фактор, усложняющий ситуацию, состоит в том, что я не использую полноценный <a href="https://quasar.dev/quasar-cli-vite/developing-capacitor-apps/introduction" rel="nofollow">Quasar</a>, и всё заработало бы сразу с ним. 

Если у вас есть возможное решение этой проблемы, пожалуйста, сообщите об этом как можно подробнее.
  • 18 октября 2024 г. 11:22
Ответы на вопрос 1
Вам необходимо настроить заголовки в WebView на iOS, чтобы добавить заголовок `Referer`. В Capacitor вы можете использовать плагин `@capacitor-community/http`, который позволяет управлять HTTP-запросами и добавлять кастомные заголовки. Также существует возможность настройки заголовков непосредственно в нативной части приложения.

Вот как это можно сделать:

### Создание собственного плагина

1. **Создайте новый плагин Capacitor.**
   Если у вас еще нет созданного плагина, вы можете создать его с помощью следующей команды:

   ```bash
   npm init @capacitor/plugin
   ```

2. **Настройте плагин для добавления заголовка.**
   В вашем плагине вам нужно будет использовать `WKWebView` и настроить `WKNavigationDelegate`, чтобы добавлять нужные заголовки.

   Пример кода для iOS (файл `MyPlugin.swift`):

   ```swift
   import Foundation
   import Capacitor

   @objc(MyPlugin)
   public class MyPlugin: CAPPlugin {
       @objc func addReferrer(_ call: CAPPluginCall) {
           guard let webView = self.bridge?.webView else {
               call.reject("WebView not found")
               return
           }

           webView.navigationDelegate = self
           call.resolve()
       }
   }

   extension MyPlugin: WKNavigationDelegate {
       public func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
           var request = webView.urlRequest
           request.addValue("your-custom-referer", forHTTPHeaderField: "Referer")
           webView.load(request)
       }
   }
   ```

3. **Используйте свой плагин в вашем приложении:**
   Теперь вы можете вызывать ваш плагин из вашего JavaScript-кода для добавления заголовка `Referer`.

   ```javascript
   import { Plugins } from '@capacitor/core';
   const { MyPlugin } = Plugins;

   // Инициализация плагина
   MyPlugin.addReferrer();
   ```

### Использование плагина @capacitor-community/http

Если вы не хотите создавать собственный плагин, можно использовать плагин `@capacitor-community/http` для настройки заголовков на уровне сетевых запросов.

1. Установите плагин:

   ```bash
   npm install @capacitor-community/http
   ```

2. Импортируйте и используйте плагин в вашем коде:

   ```javascript
   import { Http } from '@capacitor-community/http';

   const response = await Http.request({
       method: 'GET',
       url: 'https://api.your-service.com',
       headers: {
           'Referer': 'your-custom-referer'
       }
   });

   console.log(response);
   ```

### Итоги

На текущий момент стандартный `WebView` в iOS не предоставляет способа изменить заголовки для локальных запросов (таких как `capacitor://localhost`). Однако вы можете использовать собственный плагин для настройки заголовков или воспользоваться плагином `@capacitor-community/http` для работы с сетевыми запросами. 

Убедитесь также, что ваш код корректно обрабатывает ситуации, когда сетевые запросы могут не сработать на тестовых серверах или с неправильными ссылками.
Похожие вопросы