Проблема CORS в мультиплатформенном проекте Kotlin с использованием сервера с Ktor

У меня есть демо-проект, в котором я тестирую различные архитектурные подходы, шаблоны и технологии для Android. В настоящее время я работаю над серверной частью, используя Kotlin Multiplatform, и столкнулся с технической проблемой, которую не могу решить самостоятельно. Вот задача: у меня есть сервер Ktor, который по запросу возвращает список объектов:

fun main() {
    embeddedServer(Netty, port = 8080, host = "0.0.0.0", module = Application::module)
        .start(wait = true)
}

fun Application.module() {
    routing {
        get("/repos/octocat/Spoon-Knife/forks") {
            call.respondText(forksJson(), ContentType.Application.Json, HttpStatusCode.OK)
        }
    }
}

И клиент — сайт, который также использует Ktor для отправки запросов на сервер для получения списка объектов:

HttpClient {
    install(ContentNegotiation) {
        json(Json {
            prettyPrint = true
            isLenient = true
            ignoreUnknownKeys = true
        })
    }
}

Я запускаю сервер и веб-приложение на одном ноутбуке (macOS). При попытке выполнить запрос получаю следующую ошибку:

Access to fetch at 'http://localhost:8080/repos/octocat/Spoon-Knife/forks' from origin 'http://localhost:8081' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Я пробовал разные решения, например настройку CORS на сервере:

install(CORS) {
    allowMethod(HttpMethod.Options)
    allowMethod(HttpMethod.Get)
    allowMethod(HttpMethod.Post)
    allowHeader(HttpHeaders.XForwardedProto)
    allowHeader(HttpHeaders.Authorization)
    allowHeader(HttpHeaders.ContentType)
    allowCredentials = true
    anyHost() 
}

И настройки на стороне клиента:

httpClient.get("${baseUrl}repos/octocat/Spoon-Knife/forks") {
    headers.append("Access-Control-Allow-Origin", "http://localhost:8080")
    headers.append("Access-Control-Allow-Credentials", "true")
}

К сожалению, ничего не помогло добиться желаемого результата. Я был бы благодарен за любую помощь.

Никакой заголовок Access-Control-* не должен быть установлен на стороне клиента; это заголовки ответов.

jub0bs 02.06.2024 21:47

Я добавил Access-Control-* в поисках решения проблемы CORS. Существует вероятность неправильного использования. Поэтому я вынужден обратиться к сообществу за помощью. Чтобы мне подсказали, как это реализовать, чтобы работало без ошибок.

Tarasov Volodymyr 03.06.2024 07:31
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
137
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

При настройке CORS на сервере вы забыли добавить один заголовок, что и вызывает проблему. Если вы добавите заголовок для источника разрешения контроля доступа, он должен работать нормально. Вы можете добавить его следующим образом:

allowHeader(HttpHeaders.AccessControlAllowOrigin)

Спасибо за совет. ДобавленallowHeader(HttpHeaders.AccessControlAllowOrigin) в заголовок сервера. Но, к сожалению, я получаю ту же ошибку.

Tarasov Volodymyr 02.06.2024 18:57

Я обнаружил, что эта ошибка возникает, если вы запускаете сервер на локальном хосте и Интернет на одном локальном хосте. Но я не нашел как исправить. Или это особенность разработки на мультиплатформенной стороне. Тогда было бы неплохо посмотреть успешный кейс реализации сервера+веба в мультиплатформенном проекте.

Tarasov Volodymyr 02.06.2024 19:01

Я написал код создания сервера с нуля и добавил в него правила Cors, добавив к немуallowHeader(HttpHeaders.AccessControlAllowOrigin). И у меня все работало. Возможно, где-то были конфликтующие заголовки или какой-то другой дополнительный код. Окончательный вид рабочего Cors: install(CORS) { AnyHost()allowHeader(HttpHeaders.ContentType)allowHeader(HttpHeaders.AccessControlAllowOrigin) }

Tarasov Volodymyr 03.06.2024 20:56

Другие вопросы по теме