本地下载图片遇跨域错误:No 'Access-Control-Allow-Origin' header缺失
我通过以下代码调用API获取图片并展示在div中:
let newIcon = (query) => { return $.ajax({ url: "https://noun-project-proxy.herokuapp.com/v1", method: 'GET', data: { url: `icons/${query}`, params: JSON.stringify({ }) } }).then(function (response) { let image = response.icons[0].preview_url; $("#container1").append(`<div><img src="${image}"></div>`); }); }
图片在localhost环境下可以正常显示,但部署网站后出现错误:"No 'Access-Control-Allow-Origin' header is present on the requested resource"。我尝试给img添加crossOrigin='anonymous',结果本地和部署版本的图片都无法显示了,求解决办法。
别慌,咱们一步步拆解问题来解决:
1. 先搞懂问题根源
- 本地能正常显示是因为浏览器对
localhost的跨域限制非常宽松,但线上环境会严格执行同源策略,直接请求图片服务器的资源就会触发跨域拦截。 - 你加了
crossOrigin='anonymous'后反而全挂了,是因为图片所在的服务器根本没返回对应的CORS响应头(比如Access-Control-Allow-Origin: *或者你的域名),这时候浏览器会直接判定这个请求不安全,拒绝加载图片。
2. 三个可行的解决办法
办法一:复用现有代理服务器(最省心)
你已经在用https://noun-project-proxy.herokuapp.com/v1这个代理了,不如直接让它帮你转发图片请求,而不是直接用API返回的preview_url。这样所有请求都走代理,跨域问题直接被代理搞定。
修改后的代码如下:
let newIcon = (query) => { return $.ajax({ url: "https://noun-project-proxy.herokuapp.com/v1", method: 'GET', data: { url: `icons/${query}`, params: JSON.stringify({ }) } }).then(function (response) { let imagePath = response.icons[0].preview_url; // 把图片请求也交给代理转发 let proxiedImageUrl = `https://noun-project-proxy.herokuapp.com/v1?url=${encodeURIComponent(imagePath)}`; $("#container1").append(`<div><img src="${proxiedImageUrl}"></div>`); }); }
办法二:在自己的部署服务器上配置反向代理
如果你的网站部署在Nginx、Apache这类服务器上,可以自己配置反向代理来转发图片请求。比如Nginx的配置示例:
location /noun-images/ { proxy_pass https://对应的图片服务器域名/; add_header Access-Control-Allow-Origin *; }
之后把代码里的图片地址改成/noun-images/xxx这种路径,所有图片请求都会经过你的服务器转发,自然就不会有跨域问题了。
办法三:确认图片服务器是否支持CORS
如果图片服务器是公开服务,你可以去翻它的API文档,看看有没有支持CORS的配置方式,比如允许自定义Origin头。不过这个方法主动权不在你手里,优先级可以靠后。
3. 补充:为什么crossOrigin会失效?
当你给img加crossOrigin='anonymous'时,浏览器会给图片请求带上Origin头,要求服务器返回Access-Control-Allow-Origin响应头来确认允许跨域。如果服务器没返回这个头,浏览器就会直接拒绝加载图片——哪怕是本地环境也不例外,这个规则是浏览器强制执行的。
内容的提问来源于stack exchange,提问作者orangepeel




