【问题标题】:Data is UTF-8, Ajax is returning some characters incorrectly数据为 UTF-8,Ajax 错误地返回了一些字符
【发布时间】:2018-09-26 15:52:23
【问题描述】:

我花了很多时间在网上搜索并看到很多类似的答案,但找不到任何适合我的情况。

我花了一些时间将我的 MySQL 数据库从 latin1(默认)转换为 UTF-8。我清空了表(截断),并从文本文件中重新导入了数据。我已将我的页面的标题设置为使用 UTF-8 元标记:

<meta http-equiv="Content-Type" content="text/html" charset="UTF-8" />

而且到处都在使用它。当我通过 PHP 读取数据并将其输出到表单中时,数据会正确显示,如:Königstadt 之类的文本可能会出现。保存它们(更新集......)它们似乎没问题,因为当我从数据中重新读取它们时,表单中的显示是正确的。 (PHP Admin 中的显示显示“Königstadt”,这很奇怪,但是当我阅读数据时,它似乎是正确的......--我希望这是 PHPAdmin 的一些奇怪之处)

当我使用 Ajax 通过 PHP 检索数据时,似乎所有事情都对我不利的是我的 Ajax 代码。下面是一个相对简单的例程,它调用 PHP 程序为 SELECT 生成选项标签:

     function get_branches()
     {
        // numeric values that need to be passed to the
        // routine (so we show the correct item selected)
        var region = document.getElementById("search_region").value;
        // the code in load_branches needs this, but ...
        var branch = document.getElementById("search_branch").value;

        $.ajax
        ({
           type: "POST",
           url: "<?php echo $Roster_html_RootPath; ?>lookups/load_branches.php",
           data: {
                   'region' : region,
                   'local_branch' : branch
                 },
           //cache: false,
           success: function(data)
           {
              // load contents of DIV tag with id of branchoptions:
              $("#branch_options").html(data);
           }  // end success
        }); // end ajax call
     }; // end function get_branches()

  }); // end document.ready ...

返回的大部分记录都很好。然而,上面显示的 (Königstadt) 看起来像: 返回的 HTML Select 中的 Königstadt。

我一直在尝试寻找解决方案,比如为Ajax设置contentType,以下是我尝试过的东西:

contentType: "application/x-www-form-urlencoded;charset=utf-8",

这似乎根本没有任何区别。没有任何变化。

contentType: "application/text; charset=utf-8",

(或应用程序/json) 这会杀死传递给 PHP 文件的值——数据数组似乎没有到达那里,因为我从 PHP 中得到错误:

Notice: Undefined index: region in C:\xampp\htdocs\Heralds\Roster\lookups\load_branches.php on line 32

Notice: Undefined index: local_branch in C:\xampp\htdocs\Heralds\Roster\lookups\load_branches.php on line 33

我完全不知道如何正确返回值。我需要文本或 html 的版本(我在这里返回一个 html 表或选项标签),但我还需要为我的一些代码使用 json 数组来正确返回值。它们似乎都不适用于 UTF-8 编码的数据。我已经为此工作了一段时间,并且非常沮丧。我看到的解释不起作用,或者在某些情况下没有意义......

PHP lookups/load_branches.php

<?php
// if session has not started:
session_start();

// load some basic configuration, including relative paths
// and variables needed ...
include_once( "../includes/configuration.php" );

// data connection
include_once( $Roster_RootPath . "includes/connect.php");

// values from Ajax code:
$region       = $_POST["region"];
$local_branch = $_POST["local_branch"];

// open the roster_branches table and get list
if( $region > 0 ) // check only needed for find_by_branch.php
{
   $branch_statement = "select * from roster_branches where region=" .  $region . " order by local";
}
else
{
   $branch_statement = "select * from roster_branches order by local";
}

// first, get the data from the table:
$branch_result = mysqli_query( $connect, $branch_statement );
if( !$branch_result )
{
   $out = "";
   $out .= "<div class='alert alert-danger'>";
   $out .= "<p><b>Error in SQL statement ...</b><br />";
   $errornum = mysqli_errno( $connect );
   $out .= "MySQL Error Number: " . $errornum . "<br />";
   $out .= "MySQL Error: " . mysqli_error( $connect ) . "<br />";
   $out .= "SQL Statement: " . $branch_statement . "</p>";
   $out .= "</div>";
   echo $out;
   die;   
}
else
{
   $out = "";
   // create select:
   $out = "<select class='form-control' id='local_branch' name='local_branch'>\n";

   // need the blank option:
   $out .= "   <option value=0 selected></option>\n";

   while( $branch_row = mysqli_fetch_array( $branch_result ) )
   {
      $id = $branch_row["rb_id"];
      $local = $branch_row["local"];
      $selected = "";
      if( $local_branch == $id )
      {
         $selected = " selected";
      }
      $out .= "<option value=" . $id . $selected . ">" . $local . "</option> \n";
   }

   $out .= "</select>\n";
   echo $out;      
} // we have something

?>

【问题讨论】:

  • 请出示您的PHP文件lookups/load_branches.php
  • UTF-8 all the way through的可能重复
  • 会添加load_branches.php文件,不会太长,但需要确保编辑器格式正确...
  • 来自@Martin 指向的示例: contentType: "application/x-www-form-urlencoded;charset=UTF-8",没有效果; contentType:"application/x-javascript; charset:UTF-8", 打断代码(它不会将数据数组传递给 PHP 文件)

标签: php mysql ajax utf-8 utf8mb4


【解决方案1】:

我的 MySQL 数据库从 latin1 到 UTF-8(默认)。


1) 我使用了“utf8_unicode_ci”。 2)我不知道你在说什么“多字节安全功能”。我从 $_POST 读取数据时使用 mysqli_real_escape_string(),以及常用的 mysqli_query() 等函数

这是您的问题的原因。

有 3 个主要的地方可以纠正这个问题:

1)

您需要在 MySQL 中启用真正的 UTF-8 (4-byte),以便存储在 SQL 中的数据存储为正确的 UTF-8 字符。 universally 使用带有utf8mb4_ 前缀的排序规则和字符集。

2)

为确保您的应用程序/PHP 中的数据被正确保存,您需要通过设置确保数据以 UTF-8 4 字节字符的形式传递给 MySQL在您的 PHP 中将 连接字符集 转换为完整(4 字节)UTF-8:

$mysqliObject->set_charset('utf8mb4');   // object oriented style
mysqli_set_charset($connect, 'utf8mb4');    // procedural code style

3)

最后;您需要确保 PHP 对结果数据所做的任何处理都是多字节感知;通过使用mbstring 函数集。

最值得注意的是:

因此,在任何浏览器输出之前,每个 PHP 页面的顶部应该如下所示)

mb_internal_encoding('UTF-8');
mb_http_output('UTF-8');

然后,如果您对str_&lt;whatever&gt; 函数(以及其他一些函数)执行任何操作,您就会知道它不会在字符串输出到浏览器之前破坏您的字符串(在本例中为 ajx)。


【讨论】:

  • 1) 我使用了“utf8_unicode_ci”。 2)我不知道你在说什么“多字节安全功能”。我在从 $_POST 读取数据时使用 mysqli_real_escape_string() 以及常用的 mysqli_query() 等函数。
  • 我尝试将其插入到一些代码中,并得到一个错误:致命错误:在线调用 C:\xampp\htdocs\Heralds\Roster\lookups\load_branches.php 中的未定义函数 mbstring() 79
  • @KenMayer 我已经为你写了一个更有用的答案。我希望这会有所帮助
  • @KenMayer mbstring 本身并不是一个函数。请参考手册。
  • utf8 适用于像 ö 这样的简单字符。 utf8mb4 只有在处理诸如表情符号之类的代码点更高的东西时才真正需要。
【解决方案2】:

öö 的“Mojibake”。请参阅Trouble with UTF-8 characters; what I see is not what I stored 中的“Mojibake”。

但真正的问题可能发生在您从 latin1 转换时。

需要通过ALTER TABLE .. CONVERT TO CHARACTER SET utf8mb4 转换的表。任何其他技术都可能造成混乱。

任何与 MySQL 的连接都需要指定utf8mb4

【讨论】:

    猜你喜欢
    • 2014-10-08
    • 2015-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多