Instagram网页版可跨域请求i.instagram.com,为何浏览器扩展不行?
问题
我正在开发一款在Instagram网页版(instagram.com)运行的简单浏览器扩展,尝试向i.instagram.com发起请求时,始终遭遇CORS限制失败,但Instagram网页版自身却能通过Ajax发起同类请求。
我的扩展用fetch发起的请求代码如下:
// fetch("https://www.instagram.com/api/v1/{some_api_point}", { fetch("https://i.instagram.com/api/v1/{some_api_point}", { method: 'POST', redirect: 'follow', //! mode: 'cors', credentials: 'include', //! headers: { 'content-type': 'application/x-www-form-urlencoded', 'Alt-Used': 'i.instagram.com', 'Origin': 'https://www.instagram.com', 'Referer': 'https://www.instagram.com', 'Sec-fetch-dest': 'empty', 'Sec-fetch-mode': 'cors', 'Sec-fetch-site': 'same-site', 'x-asbd-id': '<...>', 'x-csrftoken': '<...>', 'x-ig-app-id': '<...>', 'x-ig-www-claim': '<hardcoded>', 'x-instagram-ajax': '<...>', } })
另外,我在Firefox开发者工具中重放Instagram的请求时,能成功获取JSON响应,无报错。
补充信息:
- 我认为请求头正确,且已通过
credentials: 'include'包含Cookie。 - 请求
www.instagram.com/api/...时不会触发CORS报错,但无数据返回,提示:
无法加载响应数据:由于请求被重定向,无可用内容
为什么同一浏览器同一页面中,Instagram自身能发起该请求,我的扩展却受CORS限制?
原因与解决办法
核心原因:执行上下文差异
Instagram网页的原生脚本属于网页自身执行上下文,浏览器会默认信任同站点域名下的脚本,向子域名i.instagram.com发起请求时不会严格触发CORS校验。
而你的扩展脚本属于独立的扩展执行上下文,哪怕注入到网页中运行,浏览器仍会将其视为第三方脚本,严格执行CORS规则。i.instagram.com的服务器未配置允许扩展域名跨域访问,因此请求被拦截。
可行解决方案
通过扩展权限绕过CORS
在扩展的manifest.json中添加对目标域名的权限:{ "host_permissions": [ "https://i.instagram.com/api/v1/*" ] }之后发起请求时可将
mode设为'no-cors'(或省略该字段),浏览器会跳过CORS校验。注入原生脚本执行请求
不要直接在扩展脚本中发起请求,而是通过注入脚本让请求在网页自身上下文运行:// 内容脚本中注入原生请求脚本 const script = document.createElement('script'); script.textContent = ` fetch("https://i.instagram.com/api/v1/{some_api_point}", { method: 'POST', credentials: 'include', headers: { /* 保留原请求头配置 */ } }).then(res => res.json()).then(data => { // 将结果传递回扩展 window.postMessage({ type: 'INSTAGRAM_API_DATA', data }, 'https://www.instagram.com'); }); `; document.body.appendChild(script); script.remove(); // 内容脚本监听返回结果 window.addEventListener('message', (event) => { if (event.origin === 'https://www.instagram.com' && event.data.type === 'INSTAGRAM_API_DATA') { // 处理获取到的数据 console.log(event.data.data); } });处理
www.instagram.com/api的重定向问题
该请求会被重定向到i.instagram.com,直接请求后者的接口即可(结合上述两种方案)。
内容的提问来源于stack exchange,提问作者Kum
相关产品推荐
相关产品推荐

