You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

前端新手调用随机图片API时遇TypeError: Cannot read property 'src' of null错误求助

搞定"Cannot read property 'src' of null"这个错误

嘿,我来帮你捋清楚这个问题!你碰到的TypeError: Cannot read property 'src' of null,本质上是你的JavaScript代码在页面元素加载完成前就执行了,导致找不到目标图片元素。

为什么会报错?

你的<script>标签放在了<head>里,浏览器是从上到下解析HTML的。当JS执行var img = document.querySelector("#photo");这行代码时,<body>里的<img id="photo">还没被渲染到页面上呢!所以querySelector找不到这个元素,返回了null,之后你尝试访问null.src,自然就抛出错误了。

另外还有个小细节:你给img.src赋值的时候用了双等号==,这是用来比较值是否相等的运算符,不是赋值用的,得改成单等号=才行!

三种修复方案任你选

方案1:把JS代码挪到页面最底部

最简单的办法就是把<script>标签放到</body>标签前面,这样所有DOM元素都加载完成后,JS才会执行:

<html>
<head>
<link rel="stylesheet" type="text/css" href="Dog app.css">
</head>
<body>
<div class="container">
<h1>Welcome to dog photo app</h1>
<img src="https://images.dog.ceo/breeds/waterdog-spanish/20180723_185544.jpg" id="photo" alt=""><br>
<form>
<input type="button" id="btn" onclick="c()" value="click me">
</form>
</div>
<!-- 把JS移到这里 -->
<script>
var btn = document.querySelector("#btn");
var img = document.querySelector("#photo");
function c(){
var xhr = new XMLHttpRequest(),
method = "GET",
url = "https://dog.ceo/api/breeds/image/random";
xhr.open(method, url, true);
xhr.onreadystatechange = function () {
if(xhr.readyState === 4 && xhr.status === 200) {
var url = JSON.parse(xhr.responseText).message;
img.src = url; // 这里改成单等号赋值
}
};
xhr.send();
}
</script>
</body>
</html>

方案2:等DOM加载完成再执行代码

如果你想保留<script>在<head>里,可以监听DOMContentLoaded事件,确保代码只在页面元素都准备好后才运行:

<html>
<head>
<script>
// 监听DOM加载完成事件
document.addEventListener('DOMContentLoaded', function() {
var btn = document.querySelector("#btn");
var img = document.querySelector("#photo");
function c(){
var xhr = new XMLHttpRequest(),
method = "GET",
url = "https://dog.ceo/api/breeds/image/random";
xhr.open(method, url, true);
xhr.onreadystatechange = function () {
if(xhr.readyState === 4 && xhr.status === 200) {
var url = JSON.parse(xhr.responseText).message;
img.src = url; // 修复赋值运算符
}
};
xhr.send();
}
// 这里也可以把按钮点击事件换成更规范的绑定方式
btn.addEventListener('click', c);
});
</script>
<link rel="stylesheet" type="text/css" href="Dog app.css">
</head>
<body>
<div class="container">
<h1>Welcome to dog photo app</h1>
<img src="https://images.dog.ceo/breeds/waterdog-spanish/20180723_185544.jpg" id="photo" alt=""><br>
<form>
<input type="button" id="btn" value="click me">
</form>
</div>
</body>
</html>

方案3:给script加defer属性

给<script>标签加上defer属性,浏览器会自动等到DOM加载完成后再执行这个脚本,不用改位置:

<html>
<head>
<!-- 加上defer属性 -->
<script defer>
var btn = document.querySelector("#btn");
var img = document.querySelector("#photo");
function c(){
var xhr = new XMLHttpRequest(),
method = "GET",
url = "https://dog.ceo/api/breeds/image/random";
xhr.open(method, url, true);
xhr.onreadystatechange = function () {
if(xhr.readyState === 4 && xhr.status === 200) {
var url = JSON.parse(xhr.responseText).message;
img.src = url; // 修复赋值运算符
}
};
xhr.send();
}
</script>
<link rel="stylesheet" type="text/css" href="Dog app.css">
</head>
<body>
<div class="container">
<h1>Welcome to dog photo app</h1>
<img src="https://images.dog.ceo/breeds/waterdog-spanish/20180723_185544.jpg" id="photo" alt=""><br>
<form>
<input type="button" id="btn" onclick="c()" value="click me">
</form>
</div>
</body>
</html>

额外小优化:用fetch替代XHR

现在更推荐用fetch API来做网络请求,代码比XMLHttpRequest简洁多了,替换后的c函数是这样的:

function c(){
fetch("https://dog.ceo/api/breeds/image/random")
.then(response => response.json())
.then(data => {
img.src = data.message;
})
.catch(err => console.error('请求出错啦:', err));
}

内容的提问来源于stack exchange,提问作者Viraj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 22:42:32