QR-код присылается с бекенда, и при нажатии на кнопку его можно скачать. На устройствах с Android, ПК и ноутбуках все работает корректно, но на iOS возникают проблемы. Как можно это исправить?

На iOS при нажатии на "Save QR" возникает ошибка: "the operation is insecure", в то время как на Android PDF-файл скачивается без проблем. Как можно устранить эту проблему? 

```javascript
"use client";

import { UserInfoBlock } from "@/src/entites/UserInfoBlock";
import api from "@/src/shared/api/api";
import { defaultToastStyles } from "@/src/shared/model/defaultStyles/defaultStyles";
import { copyTextToClipboard } from "@/src/shared/model/functions/copyToClipboard";
import { useUserStore } from "@/src/shared/store/store";
import { Button, IButtonSize } from "@/src/shared/ui/Button/Button";
import { useQuery } from "@tanstack/react-query";
import html2canvas from "html2canvas";
import { jsPDF } from "jspdf";
import Image from "next/image";
import { useEffect, useRef, useState } from "react";
import toast from "react-hot-toast";
import { QrImageSave } from "../QrImageSave/QrImageSave";
import styles from "./Qr.module.scss";

export const Qr = () => {
  const printRef = useRef(null);
  const [qrSrc, setQrSrc] = useState<string | null>(null);

  const userId = useUserStore((state) => state.data.id);
  const userName = useUserStore((state) => state.data.name);
  const userAvatar = useUserStore((state) => state.data.avatar);
  const userGoal = useUserStore((state) => state.data.goal);

  const qrLink = `https://saluttipe.site/qr_code/user/${userId}`;

  const { data } = useQuery({
    queryKey: ["qr"],
    queryFn: async () => {
      const response = await api.get("profile/me/qr-code/", {
        responseType: "blob",
      });
      return response.data;
    },
  });

  useEffect(() => {
    if (data) {
      const qrUrl = URL.createObjectURL(data);
      setQrSrc(qrUrl);
    }
  }, [data]);
```
  • 27 февраля 2025 г. 20:44
Ответы на вопрос 1
Проблема с ошибкой "the operation is insecure" на iOS связана с тем, что для загрузки файлов через JavaScript браузеры требуют соблюдения определенных условий безопасности. Эта проблема может возникать, если вы пытаетесь создать ссылку для скачивания файла (например, PDF) без явного взаимодействия пользователя (например, нажатия на кнопку).

Вот несколько подходов, которые помогут решить проблему с загрузкой QR-кода на устройствах iOS:

### 1. Используйте только Blob для ссылок

Когда создаете ссылку для скачивания файла (например, с использованием `URL.createObjectURL`), убедитесь, что вы используете `Blob` и обрабатываете его корректно. В этом случае, для создания ссылки можно воспользоваться специальным элементом `<a>`.

```javascript
const downloadFile = () => {
  if (data) {
    const blob = new Blob([data], { type: 'image/jpeg' }); // Замените 'image/jpeg' на подходящий MIME-тип
    const url = window.URL.createObjectURL(blob);

    const a = document.createElement('a');
    a.href = url;
    a.download = 'qr_code.jpg'; // Укажите имя файла для сохранения
    document.body.appendChild(a);
    a.click();
    a.remove(); // Удаляем элемент из DOM
    window.URL.revokeObjectURL(url); // Очищаем URL
  }
};
```

### 2. Убедитесь, что действие инициировано пользователем

iOS требует, чтобы действие по загрузке было явно инициировано пользователем. Убедитесь, что кнопка, которую вы используете для загрузки QR-кода, вызывает функцию скачивания:

```javascript
<Button onClick={downloadFile}>Save QR</Button>
```

### 3. Переход на использование `fetch` для запроса PDF

Если вы работаете с PDF, вам может потребоваться использовать `fetch` для запроса файла и его обработки:

```javascript
const downloadPdf = async () => {
  const response = await fetch(qrLink);
  if (!response.ok) throw new Error('Network response was not ok');
  
  const blob = await response.blob();
  const url = window.URL.createObjectURL(blob);

  const a = document.createElement('a');
  a.href = url;
  a.download = 'qr_code.pdf'; // Укажите имя файла для сохранения
  document.body.appendChild(a);
  a.click();
  a.remove(); 
  window.URL.revokeObjectURL(url);
};
```

### Заключение

Обязательно протестируйте каждое из предложений и убедитесь, что ваше приложение на iOS работает корректно. Если ни одно из этих решений не работает, попробуйте обратиться к документации по специфике работы JavaScript и файловых операций на iOS, а также изучить другие библиотеки для работы с файлами, такие как `FileSaver.js`, которые могут упростить эту задачу.
Похожие вопросы