Ktor 后端的 CORS 问题
Posted
技术标签:
【中文标题】Ktor 后端的 CORS 问题【英文标题】:CORS Issue With Ktor Backend 【发布时间】:2020-11-07 23:07:12 【问题描述】:我正在创建一个全栈应用程序,后端使用 Ktor (Kotlin) 开发,前端使用 React (TypeScript)。后端托管在 Heroku 上,而前端仍在开发中,因此我在本地运行它。
在使用 Postman 进行测试时,该 API 可以正常运行并按预期工作。这是 Ktor 配置的摘录:
@Suppress("unused")
@kotlin.jvm.JvmOverloads
fun Application.module(testing: Boolean = false)
install(CORS)
anyHost()
install(StatusPages)
// Status pages configuration
install(ContentNegotiation)
jackson
enable(SerializationFeature.INDENT_OUTPUT)
disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
disable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES)
routing
// Declaration of routes
我已启用 CORS,允许每个主机访问资源。
在 React 应用程序中,我使用 axios
作为我的 HTTP 库。这是对服务器的请求的示例:
interface LoginModel
email: string;
password: string;
interface TokenAuthModel
successful: boolean;
access_token: string;
import * as axios from 'axios';
const requestConfig =
headers:
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
,
timeout: 15000
;
async login(login: LoginModel): Promise<TokenAuthModel | null>
const req = await axios.default.post('some-url', login, requestConfig);
if (request.status === 200)
return request.data as TokenAuthModel;
return null;
返回以下错误信息:
CORS 策略已阻止从源“http://localhost:3000”访问“https://app-name.herokuapp.com/some/endpoint”处的 XMLHttpRequest:对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。
如上所述,该错误仅在从 React 前端发出请求时出现,而 Postman 调用按预期工作。
任何形式的帮助都将不胜感激。
【问题讨论】:
【参考方案1】:我用这个来做cors:
install(CORS)
method(HttpMethod.Options)
method(HttpMethod.Put)
method(HttpMethod.Delete)
method(HttpMethod.Patch)
header(HttpHeaders.Authorization)
header(HttpHeaders.ContentType)
// header("any header") if you want to add any header
allowCredentials = true
allowNonSimpleContentTypes = true
anyHost()
【讨论】:
【参考方案2】:以下适用于我的设置(Ktor/axiom 也是):
fun Application.cors()
install(CORS)
method(HttpMethod.Options)
method(HttpMethod.Put)
method(HttpMethod.Delete)
method(HttpMethod.Patch)
header(HttpHeaders.Authorization)
header(HttpHeaders.AccessControlAllowOrigin)
allowNonSimpleContentTypes = true
allowCredentials = true
allowSameOrigin = true
host(frontendHost, listOf("http", "https")) // frontendHost might be "*"
logger.info "CORS enabled for $hosts"
可能有点过分,但我刚刚遇到了与No 'Access-Control-Allow-Origin' ...
相同的问题,这就是我解决它的方法。不需要 CORS 代理。
通过 ktor 源进行调试表明缺少 header(HttpHeaders.AccessControlAllowOrigin)
是主要问题。
【讨论】:
奇怪的是,这是必要的,因为该标头是 CORS 操作的基础,但添加header(HttpHeaders.AccessControlAllowOrigin)
确实为我解决了这个问题。【参考方案3】:
您必须从 Kotlin 后端将您的来源(本地主机:3000)列入白名单。
【讨论】:
即使在将localhost
与host("localhost:3000")
列入白名单后,客户端仍然存在相同的错误。以上是关于Ktor 后端的 CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章
ktor cors 标头中的 Access-Control-Allow-Origin 问题
从 AngularJS 前端到 Spring rest 后端的 CORS 问题
Angular 2 应用程序到 Rails 5 后端的 CORS 问题