在线考试系统AJAX请求题目时特殊字符异常,ISO-8859-15编码无效
我开发的在线考试Web应用支持多语言,首次加载一切正常,但切换到第二道题时,通过AJAX携带题目ID发起请求,返回的题目详情里数据库存储的特殊字符无法正常显示(直接返回原特殊字符)。我已经在PHP文件(questions.php)和AJAX文件(show_ques.php)中配置了ISO-8859-15编码,但问题仍未解决。
相关代码
questions.php(PHP后端文件)
<?php session_start(); ?> <?php header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache"); header('Content-Type: text/html; charset=ISO-8859-15'); ini_set('session.use_cookies', '0'); include '../inc_classes.php'; if((time()-$_SESSION['last_login_time'])>900) $_SESSION['last_login_time']=""; else $_SESSION['last_login_time']=time(); $select_question_last = " select question_title from question where question_id='".$question_id."'" ; $ptrs_last_que = mysql_query($select_question_last) ; $i=0 ; while($data_ptr_last_que = mysql_fetch_array($ptrs_last_que)) { echo $question_title = stripslashes($data_ptr_last_que['question_title']); } ?>
show_ques.php(AJAX前端文件)
$.ajax({ url: url2, type: "get", contentType: "text/xml;charset=ISO-8859-15", data: paramss, cache: false, success: function(html) { //alert(html) if (html.trim() == 'logout') { alert('You can not attempt exam any mor...'); } } });
嘿,我看了你的代码和问题描述,虽然你已经设置了前后端的编码,但核心问题大概率出在数据库连接的编码没有和ISO-8859-15匹配,还有AJAX请求的内容类型设置不对。下面是一步步的修复方案:
1. 强制设置数据库连接的字符集
你用的是已经废弃的mysql_*扩展(后续建议换成mysqli或PDO,更安全),在执行查询之前,必须确保数据库连接使用的是ISO-8859-15编码。在include '../inc_classes.php';这行之后,添加:
mysql_set_charset('ISO-8859-15');
这一步非常关键——如果数据库连接编码和你输出的编码不一致,哪怕header设置对了,特殊字符还是会乱码。
2. 修正AJAX的请求配置
你现在AJAX的contentType设成了text/xml,但后端返回的是text/html,这会导致浏览器解析数据时编码不匹配。改成和后端一致的类型,同时明确指定数据类型:
$.ajax({ url: url2, type: "get", contentType: "text/html;charset=ISO-8859-15", // 改为text/html,和后端header一致 dataType: 'html', // 明确告诉jQuery解析为HTML data: paramss, cache: false, success: function(html) { if (html.trim() == 'logout') { alert('You can not attempt exam any more...'); // 顺手补全了拼写错误 } } });
3. 检查数据库表的字符集
确认你的question表和question_title字段的字符集是latin9(MySQL里ISO-8859-15对应的字符集名称是latin9)。可以用这条SQL查看表的字符集:
SHOW CREATE TABLE question;
如果字段字符集不对,执行这条SQL修改:
ALTER TABLE question MODIFY COLUMN question_title TEXT CHARACTER SET latin9 COLLATE latin9_general_ci;
4. 替换废弃的mysql_*扩展(可选但强烈推荐)
mysql_*扩展在PHP 5.5之后就被废弃了,现在已经从新版本PHP中移除,换成mysqli扩展更安全。比如把查询部分改成:
// 假设你的数据库连接是$conn(需要在inc_classes.php里改成mysqli连接) $select_question_last = "SELECT question_title FROM question WHERE question_id = ?"; $stmt = mysqli_prepare($conn, $select_question_last); mysqli_stmt_bind_param($stmt, "s", $question_id); mysqli_stmt_execute($stmt); mysqli_stmt_bind_result($stmt, $question_title); while(mysqli_stmt_fetch($stmt)){ echo stripslashes($question_title); } mysqli_stmt_close($stmt);
同时设置mysqli的连接编码:
mysqli_set_charset($conn, 'ISO-8859-15');
按这个步骤来,应该就能解决特殊字符显示的问题了。
内容的提问来源于stack exchange,提问作者kiran

