多种方式请求指定URL的JSON数据失败,寻求技术解决方案
嘿,你这情况我太熟了——十有八九是**跨域资源共享(CORS)**在搞鬼!浏览器的安全机制会拦下同域以外的前端请求,除非目标服务器明确给你的访问源开了绿灯。
先看你写的fetch代码,逻辑完全没问题:
let url = "https://www.sodexo.fi/ruokalistat/output/daily_json/27843/2018/04/25/fi"; fetch(url) .then(response => response.json()) .then(json => gotData(json)) function gotData(data) { console.log(data); }
但浏览器会抛出类似No 'Access-Control-Allow-Origin' header is present的错误,就是因为Sodexo的这个接口没配置CORS允许你的前端域名访问。
你试过fetchJsonp也没用?正常,因为JSONP要求服务器返回的是包裹在函数调用里的内容,而这个接口返回的是纯JSON,自然解析失败。
给你几个实用的解决办法:
搭个后端代理中转请求
后端请求不受浏览器CORS限制,所以你可以自己写个简单的服务,让它帮你去拿Sodexo的数据,再转给前端。比如用Node.js+Express写个小代理:// Node.js 示例代码 const express = require('express'); const fetch = require('node-fetch'); const app = express(); app.get('/get-sodexo-menu', async (req, res) => { const targetUrl = "https://www.sodexo.fi/ruokalistat/output/daily_json/27843/2018/04/25/fi"; try { const response = await fetch(targetUrl); const menuData = await response.json(); res.json(menuData); } catch (err) { res.status(500).send('请求出错啦'); } }); app.listen(3000, () => console.log('代理服务跑在3000端口啦'));之后前端就请求
http://localhost:3000/get-sodexo-menu,就能顺利拿到数据了。查下Sodexo有没有官方开放API
不少餐饮品牌会提供专门的开发者API,这类API一般都会配置好CORS。你可以去Sodexo的官网找找开发者文档,要是有官方API,直接用它就没跨域烦恼了。开发测试用浏览器插件临时绕CORS
要是只是本地调试,装个像Allow CORS: Access-Control-Allow-Origin的插件,临时关掉浏览器的CORS限制就行。但注意哦,这只适合开发,绝对不能用到生产环境里。
对了,你试的JQuery、p5.js的XHR这些方法,本质都是前端发起的请求,都会碰到同样的CORS问题,所以核心还是得解决跨域的事儿。
内容的提问来源于stack exchange,提问作者Jussi Roos

