适配Safari:JS前端与FastAPI后端跨域请求失败问题排查
Safari下HTTPS前端请求HTTP后端API失败问题
我的Web应用在Safari浏览器中无法正常运行:前端是JavaScript实现,运行在https://localhost:3000;后端是Python FastAPI服务,运行在http://localhost:8000。应用在Chrome和Firefox中完全正常,但Safari里彻底无法工作。
Safari控制台错误信息
[Warning] [blocked] The page at https://localhost:3000/#/app was not allowed to display insecure content from http://localhost:8000/llmodels/. (taskpane.js, line 62967) [Error] Not allowed to request resource tryCatch (taskpane.js:62967:2409) (anonymous function) (taskpane.js:62967:1973) asyncGeneratorStep (taskpane.js:62969:104) _next (taskpane.js:62971:213) (anonymous function) (taskpane.js:62971:370) initializePromise (taskpane.js:26483) Promise (taskpane.js:26911) (anonymous function) (taskpane.js:62971:109) tryCatch (taskpane.js:59336:2409) (anonymous function) (taskpane.js:59336:1973) asyncGeneratorStep (taskpane.js:59338:104) _next (taskpane.js:59340:213) (anonymous function) (taskpane.js:59340:370) initializePromise (taskpane.js:26483) Promise (taskpane.js:26911) (anonymous function) (taskpane.js:59340:109) componentWillMount (taskpane.js:59867) callComponentWillMount (taskpane.js:45759) mountClassInstance (taskpane.js:45853) updateClassComponent (taskpane.js:50401) beginWork$1 (taskpane.js:56910) performUnitOfWork (taskpane.js:55749) workLoopSync (taskpane.js:55677) renderRootSync (taskpane.js:55640) performSyncWorkOnRoot (taskpane.js:55263) performSyncWorkOnRoot (anonymous function) (taskpane.js:44302) unstable_runWithPriority (taskpane.js:76263) flushSyncCallbackQueueImpl (taskpane.js:44297) flushSyncCallbackQueue (taskpane.js:44284) scheduleUpdateOnFiber (taskpane.js:54863) updateContainer (taskpane.js:58452) legacyRenderSubtreeIntoContainer (taskpane.js:59007) render (taskpane.js:62764) (anonymous function) (taskpane.js:62780) (anonymous function) (office.js:76:23256) t (office.js:76:22656) s (office.js:76:30352) c (office.js:76:4170) (anonymous function) (office.js:76:4259) z (office.js:76:30830) m (office.js:76:6322) [Error] Fetch API cannot load http://localhost:8000/llmodels/ due to access control checks. tryCatch (taskpane.js:62967:2409) (anonymous function) (taskpane.js:62967:1973) asyncGeneratorStep (taskpane.js:62969:104) _next (taskpane.js:62971:213) (anonymous function) (taskpane.js:62971:370) initializePromise (taskpane.js:26483) Promise (taskpane.js:26911) (anonymous function) (taskpane.js:62971:109) tryCatch (taskpane.js:59336:2409) (anonymous function) (taskpane.js:59336:1973) asyncGeneratorStep (taskpane.js:59338:104) _next (taskpane.js:59340:213) (anonymous function) (taskpane.js:59340:370) initializePromise (taskpane.js:26483) Promise (taskpane.js:26911) (anonymous function) (taskpane.js:59340:109) componentWillMount (taskpane.js:59867) callComponentWillMount (taskpane.js:45759) mountClassInstance (taskpane.js:45853) updateClassComponent (taskpane.js:50401) beginWork$1 (taskpane.js:56910) performUnitOfWork (taskpane.js:55749) workLoopSync (taskpane.js:55677) renderRootSync (taskpane.js:55640) performSyncWorkOnRoot (taskpane.js:55263) performSyncWorkOnRoot (anonymous function) (taskpane.js:44302) unstable_runWithPriority (taskpane.js:76263) flushSyncCallbackQueueImpl (taskpane.js:44297) flushSyncCallbackQueue (taskpane.js:44284) scheduleUpdateOnFiber (taskpane.js:54863) updateContainer (taskpane.js:58452) legacyRenderSubtreeIntoContainer (taskpane.js:59007) render (taskpane.js:62764) (anonymous function) (taskpane.js:62780) (anonymous function) (office.js:76:23256) t (office.js:76:22656) s (office.js:76:30352) c (office.js:76:4170) (anonymous function) (office.js:76:4259) z (office.js:76:30830) m (office.js:76:6322)
前端请求代码
async getModels() { const response = await fetch("http://localhost:8000/llmodels/",{ method: "GET", mode: "cors", headers: { "Content-Type": "application/json", "Access-Control-Allow-Methods": "GET, POST, DELETE, OPTIONS", }, }); const returner = await response.json(); return returner; };
后端配置代码
from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware app = FastAPI(docs_url="/docs/") origins = [ "http://localhost:3000", "https://localhost:3000", ] app.add_middleware( CORSMiddleware, allow_origins=origins, allow_credentials=True, allow_methods=["GET", "POST", "DELETE", "OPTIONS"], allow_headers=["Content-Type", "x-requested-with", "Access-Control-Allow-Methods"], ) @app.get("/llmodels/") def get_models(): llm_models = {"model1": "model1", "model2": "model2"} return models
已做的排查
- 针对Safari不允许CORS通配符的特性,已经在后端配置中明确指定了
allow_methods和allow_headers的具体值,未使用通配符 - 排除缓存影响:使用无痕模式打开、清空浏览器缓存后首次访问,问题依然存在
- 查阅过类似问题,但该问题由缓存文件导致,与当前情况不符
请问有人知道解决方案吗?如需更多信息请告知!
内容的提问来源于stack exchange,提问作者Johannes G
相关产品推荐
相关产品推荐

