JavaScript请求Bing接口遇CORS问题:浏览器可访问但代码报错求解
解决Bing每日图片接口的CORS问题
为什么浏览器直接访问正常,XHR请求却报错?
浏览器地址栏直接访问接口时,属于浏览器发起的顶级页面请求,不受跨域资源共享(CORS)规则限制,所以能正常看到返回内容。
而用XMLHttpRequest(或fetch)发起请求时,属于网页脚本发起的跨域请求,浏览器会自动触发CORS校验流程:
- 浏览器在请求头中带上当前页面的源信息;
- 服务器返回响应时,需要包含
Access-Control-Allow-Origin头,明确允许哪些源的脚本访问该资源; - Bing的这个接口没有返回该头,所以浏览器会拦截响应,即使状态码是200,脚本也拿不到数据,同时抛出
CORS header 'Access-Control-Allow-Origin' missing错误。
服务器确实可以通过请求头(比如User-Agent)识别客户端类型,但这不是当前CORS错误的核心原因——不管你怎么改请求头,只要是网页脚本发起的跨域请求,浏览器都会做CORS校验,除非服务器明确允许你的源。
解决办法
方案1:使用JSONP绕过CORS限制
Bing的图片接口支持JSONP格式,通过动态创建script标签加载资源,不受CORS规则约束:
// 定义回调函数,处理返回的JSON数据 function handleBingImage(data) { // 拼接完整的图片URL const fullImageUrl = 'https://www.bing.com' + data.images[0].url; // 设置为页面背景图 document.body.style.backgroundImage = `url(${fullImageUrl})`; } // 发起JSONP请求 function getBingBackground() { const script = document.createElement('script'); // 接口地址加上callback参数,指定回调函数名 script.src = 'https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&callback=handleBingImage'; document.head.appendChild(script); } // 调用函数获取图片 getBingBackground();
方案2:后端代理请求
自己搭建一个后端接口,由后端发起请求获取Bing的数据,再返回给前端(后端请求不受浏览器CORS限制)。以Node.js + Express为例:
const express = require('express'); const axios = require('axios'); const app = express(); // 自定义代理接口 app.get('/api/bing-image', async (req, res) => { try { const bingResponse = await axios.get('https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1'); res.json(bingResponse.data); } catch (err) { res.status(500).send('请求Bing接口失败'); } }); // 启动服务 app.listen(3000, () => { console.log('代理服务运行在 http://localhost:3000'); });
前端请求自己的代理接口即可:
async function getBingImage() { const response = await fetch('http://localhost:3000/api/bing-image'); const data = await response.json(); const fullImageUrl = 'https://www.bing.com' + data.images[0].url; document.body.style.backgroundImage = `url(${fullImageUrl})`; } getBingImage();
注意点
你的代码中请求的是format=xml格式的接口,但你需要的是JSON数据,记得把URL中的format=xml改成format=js。
内容的提问来源于stack exchange,提问作者acke
相关产品推荐
相关产品推荐

