Rails中AJAX请求返回HTML页面而非跳转渲染的问题求助
嘿,我明白你遇到的问题了——当@orderComplete参数不存在时,后端渲染的收据页面HTML被当作AJAX响应返回,而不是让浏览器直接加载这个页面。这是因为AJAX请求的本质是后台异步获取数据,浏览器不会自动把返回的HTML渲染成新页面,得调整前后端的交互逻辑才行。
下面给你两种可行的解决方案:
方案一:后端返回跳转URL,前端主动跳转
这种方式最直接,后端告诉前端要跳转到哪个页面,前端执行跳转动作。
修改后端Rails代码
在else分支(也就是@orderComplete为空的情况)里,判断是否是AJAX请求,返回包含收据页面URL的JSON:
else puts 'OrderComplete Parameter is blank' # 区分AJAX和普通请求 if params[:xhr_request] # 返回收据页面的路由地址,让前端跳转 render json: { redirect_to: receipt_path(campaign: @campaign) } else # 非AJAX请求直接渲染页面 render 'receipt', layout: 'receipt', campaign: @campaign end end
注意:receipt_path是假设你的收据页面路由名称,要换成你项目里实际的路由(比如如果是get '/receipt', to: 'orders#receipt',那路由名就是receipt_path)。
修改前端JavaScript代码
在AJAX的then回调里,增加对redirect_to字段的判断,收到后执行页面跳转:
}).then((function(_this) { return function(response) { if(typeof response.data == 'undefined' || response.data == null || !response.data) { console.log('Error: missing Order Number from Order Confirmation data.', response.data); } console.log('Order Confirmation response data object:' , response.data); if(orderComplete) { var redirectUrl = 'http://' + orderComplete // 这里修正了你原来的参数拼接错误:多个参数要用&连接,不是多个? var order_params = `?oid=${response.data.oid}&cart=${response.data.cart}&total=${response.data.total}` window.location.href = redirectUrl + order_params; } else if(response.data.redirect_to) { // 跳转到收据页面 window.location.href = response.data.redirect_to; } }; })(this));
方案二:后端发送重定向响应(需前端配合)
如果你更倾向于后端主导重定向逻辑,可以用redirect_to,但AJAX请求下还是需要前端处理:
修改后端代码
else puts 'OrderComplete Parameter is blank' if params[:xhr_request] // 给AJAX请求返回重定向状态码和目标URL render json: { redirect_to: receipt_path(campaign: @campaign) }, status: :see_other else // 普通请求直接重定向 redirect_to receipt_path(campaign: @campaign) end end
前端的修改和方案一完全一致,都是在回调里判断redirect_to并跳转。
为什么原来的代码不行?
你之前直接render 'receipt'时,后端会把收据页面的HTML打包成AJAX响应返回给前端,但AJAX请求不会触发浏览器的页面渲染——这些HTML只是存在前端的response.data里,不会自动替换当前页面。所以必须通过window.location.href主动跳转,让浏览器重新加载目标页面。
另外提一句:你前端代码里注释掉的window.location.href = ${baseUrl}/receipt;其实思路是对的,只是缺少了后端的触发信号,现在加上后端返回的跳转指令就可以正常工作了。
内容的提问来源于stack exchange,提问作者Errol Wallace

