使用jQuery从URL获取JSON失败,遇跨域错误求解决方案
嗨,这个问题我太熟了!你遇到的是**跨域资源共享(CORS)**限制,不是你代码写错了,是浏览器的同源安全策略在搞事情~
为什么会出现这个错误?
浏览器有个默认的安全规则:不允许从一个域名(或者本地文件,也就是你这里的Origin 'null')直接请求另一个域名的资源,除非目标服务器通过Access-Control-Allow-Origin头明确允许你的来源。Bittrex的这个API没有配置允许null来源的访问,所以浏览器直接拦截了你的请求。
怎么解决?这里有几个靠谱的方案:
1. 优先用JSONP(最简单的方案)
幸运的是,Bittrex的v1.1 API支持JSONP格式——这是一种绕过CORS限制的经典方式,原理是利用<script>标签不受同源策略限制的特性。你只需要在请求URL后面加上&callback=?,jQuery会自动帮你处理剩下的事情:
$.getJSON('https://bittrex.com/api/v1.1/public/getticker?market=usdt-btc&callback=?', function(response) { console.log('成功获取到数据:', response); // 在这里处理你的业务逻辑,比如渲染数据到页面 }) .fail(function(jqXHR, textStatus, errorThrown) { console.error('请求失败啦:', textStatus, errorThrown); });
当你添加callback=?后,jQuery会自动生成一个随机的回调函数名,服务器返回的数据会被包裹在这个函数里,浏览器加载这个script标签时就会执行该函数,你就能拿到数据了。
2. 搭建后端代理(适合生产环境)
如果后续遇到不支持JSONP的API,或者你需要对请求做额外处理,最好的方式是自己搭建一个后端代理:
- 写一个后端接口(比如用Node.js、PHP、Python等),让这个接口去请求Bittrex的API
- 前端页面请求你自己的后端接口,因为是同域名,就不会有跨域问题了
举个Node.js(Express)的简单例子:
const express = require('express'); const axios = require('axios'); const app = express(); app.get('/api/get-btc-ticker', async (req, res) => { try { const response = await axios.get('https://bittrex.com/api/v1.1/public/getticker?market=usdt-btc'); res.json(response.data); } catch (error) { res.status(500).json({ error: '请求失败' }); } }); app.listen(3000, () => console.log('代理服务器运行在3000端口'));
然后前端请求http://localhost:3000/api/get-btc-ticker就可以了。
3. 临时关闭浏览器跨域限制(仅开发测试用)
如果你只是本地开发测试,不想折腾代理或JSONP,可以给浏览器加启动参数关闭跨域安全检查:
- Chrome:在命令行输入
chrome.exe --disable-web-security --user-data-dir=C:\MyChromeDevUserData(Windows),或者open -a Google\Chrome --args --disable-web-security --user-data-dir=/tmp/chrome_dev(Mac) - 注意:这个方法只适合开发,绝对不能用于日常浏览,会带来安全风险!
总结
优先用JSONP方案,因为Bittrex已经支持,改一行代码就能解决问题。如果是生产环境或者API不支持JSONP,就用后端代理的方式。
内容的提问来源于stack exchange,提问作者PoorProgrammer

