Я генерирую возобновляемый URL-адрес на php, который затем передаю в свое угловое приложение для загрузки файла.
Мои файлы успешно загружаются в хранилище, о чем свидетельствует то, что имя файла находится в сегменте хранилища, его можно загрузить и использовать. Однако я всегда получал ответ об ошибке, связанный с CORS.
Это внутренний PHP-код, который генерирует URL-адрес.
Код: Выделить всё
public function generateResumableUploadUrl($engagementId, $fileType){
global $logger;
try {
// Step 1: Decode JWT credentials
$logger->log(LOG_LEVEL_DEBUG, 'Decoding JWT credentials for resumable upload URL', __FILE__, $engagementId);
$credentials = $this->decodeJwt();
if (!$credentials) {
throw new Exception('Failed to decode JWT credentials.');
}
$logger->log(LOG_LEVEL_DEBUG, 'JWT credentials decoded successfully', __FILE__, $engagementId);
// Step 2: Initialize Google Cloud Storage client
$logger->log(LOG_LEVEL_DEBUG, 'Initializing Google Cloud Storage client', __FILE__, $engagementId);
$storage = new StorageClient([
'keyFile' => $credentials,
]);
// Step 3: Retrieve the bucket
$yoyo_optimiser = yoyo_optimiser::get_instance();
$bucketName = $yoyo_optimiser->get_yoyo_storage_bucket();
$client = $yoyo_optimiser->get_yoyo_client();
$logger->log(LOG_LEVEL_DEBUG, 'Attempting to retrieve bucket: ' . $bucketName, __FILE__, $engagementId);
$bucket = $storage->bucket($bucketName);
if (!$bucket) {
throw new Exception('Failed to access bucket: ' . $bucketName);
}
$logger->log(LOG_LEVEL_DEBUG, 'Bucket retrieved successfully: '. print_r($bucket,true), __FILE__, $engagementId);
// Step 4: Create a resumable upload session
$fileName = $client . '/staging/' . $engagementId . $fileType;
//$logger->log(LOG_LEVEL_DEBUG, 'Creating resumable upload session for file: ' . $fileName, __FILE__, $engagementId);
$uploader = $bucket->getStreamableUploader(fopen('php://temp', 'rb'), [
'name' => $fileName,
'resumable' => true,
'contentType' => 'application/octet-stream',
]);
// Generate the upload URI
$resumableUrl = $uploader->getResumeUri();
$logger->log(LOG_LEVEL_INFO, 'Resumable upload URL generated successfully: ' . $resumableUrl, __FILE__, $engagementId);
return $resumableUrl;
} catch (Exception $e) {
// Error handling and logging
$logger->log(LOG_LEVEL_ERROR, 'Exception encountered while generating resumable upload URL: ' . $e->getMessage(), __FILE__, $engagementId);
$logger->log(LOG_LEVEL_ERROR, 'Error code: ' . $e->getCode(), __FILE__, $engagementId);
$logger->log(LOG_LEVEL_ERROR, 'Stack trace: ' . $e->getTraceAsString(), __FILE__, $engagementId);
return false;
}
}
Обратите внимание, что фактическое имя корзины считывается и добавляется... в идентификатор. Однако, как уже говорилось, URL-адрес позволяет успешную загрузку.
Далее это моя политика Cors в сегменте
Код: Выделить всё
[
{
"origin": ["*"],
"method": ["GET", "HEAD", "PUT", "POST", "DELETE", "OPTIONS"],
"responseHeader": [
"Content-Type",
"Content-Length",
"Content-Range",
"Range",
"X-Requested-With",
"X-Goog-Resumable",
"Authorization",
"Origin"
],
"maxAgeSeconds": 3600
}
]
Код: Выделить всё
private async uploadFileWithProgress(
resumableUrl: string,
fileBlob: Blob,
startByte: number,
totalSize: number,
engagementId: string
): Promise {
this.logger.debug(
`Starting upload for engagementId: ${engagementId}`,
'VideoUploadService',
'@4.0'
);
this.logger.debug(
`Upload details: resumableUrl=${resumableUrl}, startByte=${startByte}, totalSize=${totalSize}`,
'VideoUploadService',
'@4.0.1'
);
try {
const headers = {
'Content-Type': fileBlob.type || 'application/octet-stream',
'Content-Range': `bytes ${startByte}-${startByte + fileBlob.size - 1}/${totalSize}`,
};
this.logger.debug(
`Headers: ${JSON.stringify(headers)}`,
'VideoUploadService',
'@4.0.2'
);
const response = await fetch(resumableUrl, {
method: 'PUT',
headers,
body: fileBlob,
});
if (response.ok) {
this.logger.info(
`File uploaded successfully for engagementId: ${engagementId}`,
'VideoUploadService',
'@4.1'
);
// Update progress
const uploadedBytes = startByte + fileBlob.size;
const progressPercentage = (uploadedBytes / totalSize) * 100;
this.logger.debug(
`Upload progress: ${progressPercentage.toFixed(2)}%`,
'VideoUploadService',
'@4.2'
);
this.progressSubject.next(progressPercentage);
await this.saveUploadProgress(engagementId, uploadedBytes, totalSize);
return true;
} else {
const errorText = await response.text();
this.logger.error(
`File upload failed. Status: ${response.status}, Response: ${errorText}`,
'VideoUploadService',
'@4.3'
);
return false;
}
} catch (error: any) {
this.logger.error(
`Error during file upload: ${error.message || error}`,
'VideoUploadService',
'@5'
);
this.logger.debug(
`Failed fetch details: resumableUrl=${resumableUrl}, startByte=${startByte}, totalSize=${totalSize}, fileBlob size=${fileBlob.size}`,
'VideoUploadService',
'@5.1'
);
return false;
}
}
[ошибка] — ошибка при загрузке файла: не удалось получить VideoUploadService@5
и
[ошибка] — не удалось загрузить видео для взаимодействия. Идентификатор:
e6e32005-a066-4f30-a171-2dde3c468813 VideoUploadService @2.1
Сетевой запрос в браузере



Наконец, я проверил это: не удалось исправить политику CORS в облачном хранилище Google, но похоже, не мог этого понять. и некоторые другие.
Заранее спасибо, так как я использовал метод проб и ошибок, читал документацию и не мог понять, в чем проблема. Открыт для других решений, если есть предложения. Целью является поддержка загрузки на стороне клиента для незарегистрированных пользователей, которым был предоставлен защищенный URL-адрес через мой сервер.
Подробнее здесь: https://stackoverflow.com/questions/792 ... uploaded-b