如何通过指定页面URL获取页面内唯一img标签的src链接
问题背景
应用存在访问地址:http://mydomain/hr-attendance/auto-change-qrcode,访问该URL时页面仅展示一张二维码图片,页面源码内包含唯一的<img>标签,需要通过给定的页面URL获取该图片的src链接。
相关后端代码(Odoo Python):
@http.route('/hr-attendance/auto-change-qrcode', auth='user', type='http') def auto_change_qrcode(self): hr_employee_qrcode_ids = secrets.choice( request.env['hr.employee.qrcode'].sudo().search([('state', '=', 'unused')], limit=1)) secret = hr_employee_qrcode_ids.auto_change_qrcode() return http.request.render('aqur_attendance.attendance_qrcode', {'secret': secret})
现有待调整的前端JavaScript代码:
start: function () { var self = this; self.session = Session; var def = this._rpc({ model: 'hr.employee.qrcode', method: 'search_read', args: [[['id', '=', 122003]]], }) .then(function (hremplpoyeeqrcode){ self.qrcode_secret = hremplpoyeeqrcode[0]['secret']; self.qr_code_url = self.session.url('/hr-attendance/auto-change-qrcode'); self.$el.html(QWeb.render("AqurAttendanceQRCodeKioskMode", {widget: self})); self.start_clock(); }); setInterval(function () { $('.View').fadeOut('slow', function() { $(this).load('/echo/json/', function() { $(this).fadeIn('slow'); }); }); }, 3000); // refresh every 3000 milliseconds },
解决方案
可根据业务场景二选一实现:
方案1:前端侧请求页面解析img标签
不直接用.load()把返回内容塞入DOM,先拿到完整HTML文本,用DOMParser解析后提取img的src即可,调整后的定时刷新代码如下:
setInterval(function () { const viewEl = $('.View'); viewEl.fadeOut('slow', function() { // 请求目标页面内容 fetch(self.qr_code_url, { credentials: 'include' // 携带Odoo登录鉴权cookie,避免被重定向到登录页 }) .then(res => res.text()) .then(htmlText => { // 解析返回的HTML结构 const parser = new DOMParser(); const doc = parser.parseFromString(htmlText, 'text/html'); // 提取页面唯一img的src const qrImgSrc = doc.querySelector('img').src; // 直接给页面已有img标签赋值即可,无需整页替换 viewEl.find('img.qrcode').attr('src', qrImgSrc); viewEl.fadeIn('slow'); }) }); }, 3000);
注意:请求必须携带credentials: 'include',路由设置了auth='user',不带登录态的请求无法拿到正确页面内容。
方案2:后端直接返回图片地址(推荐,性能稳定性更优)
现有路由返回完整渲染HTML的逻辑多了一层不必要的模板渲染开销,可直接修改后端路由返回JSON格式的图片地址,前端直接取值使用,避免HTML解析的额外消耗,也不会因为模板结构调整导致选择器失效:
调整后端路由代码
@http.route('/hr-attendance/auto-change-qrcode-src', auth='user', type='json', methods=['POST']) def get_auto_change_qrcode_src(self): hr_employee_qrcode = secrets.choice( request.env['hr.employee.qrcode'].sudo().search([('state', '=', 'unused')], limit=1)) secret = hr_employee_qrcode.auto_change_qrcode() # 按照原有模板内img的src生成规则拼接地址返回 return f'/hr-attendance/qrcode/img?secret={secret}'
前端直接调用rpc取地址
setInterval(function () { const viewEl = $('.View'); viewEl.fadeOut('slow', function() { self._rpc({ route: '/hr-attendance/auto-change-qrcode-src' }).then(imgSrc => { viewEl.find('img.qrcode').attr('src', imgSrc); viewEl.fadeIn('slow'); }) }); }, 3000);
注意事项
- 如果坚持用原有整页load的逻辑,也可以在load完成的回调里直接查找img提取src:
但这种方式会替换容器内全部DOM,如果页面存在其他交互元素很容易被覆盖,不推荐使用。$(this).load(self.qr_code_url, function() { const imgSrc = $(this).find('img').attr('src'); // 自定义后续逻辑 $(this).fadeIn('slow'); }); - 原有代码里load的地址
/echo/json/是mock测试接口,实际使用时需要替换为自己的二维码页面地址。
内容的提问来源于stack exchange,提问作者Tri
相关产品推荐
相关产品推荐

