After utilizing encode_json, accented characters are experiencing double encoding

We are currently experiencing an issue with the encode_json function while using use JSON::XS qw(encode_json);. Our web-based project is built on Perl, JavaScript, jQuery, and MySQL as the backend.

In one specific screen within the application, the user's name is displaying inaccurately.

The problem arises due to the fact that the user's name is in Spanish and includes accented characters. The database table where we store this information follows an old schema with a charset of latin1. However, during data retrieval, we convert and encode it into UTF-8 format.

select CONVERT(CAST(CONVERT(u.last_name USING latin1) AS BINARY) USING utf8) AS last_name from user where user_id = 'XXX'

In the storage structure for the database results, everything looks correct.

{ last_name => Cvas García}

This structured data is passed to a JavaScript function responsible for rendering the page.

$data_json = encode_json( $data )

However, when printing $data_json, the accented characters once again appear distorted.

"user_permissions":[{"last_name":"Cvas García"}]},

We are seeking assistance in resolving this issue, whether it involves adjustments in MySQL, Perl, or JavaScript code.

Answer №1

The character set used in the table is not important. MySQL will automatically convert from the table's encoding to the connection's encoding. After that, you will need to decode it on the Perl side, either explicitly or by passing mysql_enable_utf8 => 1 to the connect function. I suggest using the latter option.

use utf8;                             # Source code encoded with UTF-8.
use open ':std', ':encoding(UTF-8)';  # Terminal expects/provides UTF-8.

use DBI      qw( );
use JSON::XS qw( encode_json );

my $user_id = "...";

my $dsn = "...";
my $user = "...";
my $password = "...";

my $dbh = DBI->connect("dbi:mysql:".$dsn, $user, $password, {
   PrintError => 0,
   RaiseError => 1,
   mysql_enable_utf8 => 1,  # Switch to UTF-8 for communication and decoding.
});

my $name = $dbh->selectrow_array("
   SELECT `last_name`
     FROM `user`
    WHERE `user_id` = ?
", undef, $user_id);

# Encoding handled by "use open".
print(sprintf("%vX", $name), "\n");        # 47.61.72.63.ED.61
print($name, "\n");                        # García

# Encoding handled by "use open".
my $json = JSON::XS->new->encode([$name]);
print(sprintf("%vX", $json), "\n");        # 5B.22.47.61.72.63.ED.61.22.5D
print($json, "\n");                        # ["García"]

binmode(STDOUT); # Override "use open".
my $json_utf8 = JSON::XS->new->utf8->encode([$name]);  # aka encode_json([$name])
print(sprintf("%vX", $json_utf8), "\n");   # 5B.22.47.61.72.63.C3.AD.61.22.5D
print($json_utf8, "\n");                   # ["García"]

Answer №2

Give this a shot

require 'json'
require 'utf8'
require 'data_printer'
utf8.encode(data) unless (utf8.is_utf8(data))
print encode_json(data)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Variables are losing their way in the vast expanse of self-submitting

I have a form that needs to be submitted on the same page (index.php) and I want to capture the entered information as a JavaScript variable. <?php $loginid = $_POST[username] . $_POST[password]; ?> Here is some basic code: <script> var pass ...

Error: The $filter function in AngularJS is not recognized

I have been attempting to inject a filter into my controller and utilize it in the following manner: angular .module('graduateCalculator', []) .filter('slug', function() { return function(input) { ...

What is the best way to apply a CSS class to the button that has been clicked when there are multiple buttons using jQuery?

My goal is to display specific cards when a particular button is clicked, adding a class called category_btn_active to the clicked button. For example, if the user clicks on "Services", then the service cards will be shown. The filtering functionality work ...

Tips for effectively splitting arrays nested within an array using JavaScript

Here is an example of slicing an array to generate a new one: var array= [ [1,"dataA","dataB","dataC","dataD"...], [2,"dataA","dataB","dataC","dataD"...], [3,"dataA","dataB","dataC","dataD"...], [4,"dataA","dataB","dataC","dataD"...]... ...

Start a fresh project using the Teamweek API with jQuery integration

After successfully acquiring the planning details from Teamweek using the API (Get projects from Teamweek in jQuery), I am now looking to feed Teamweek a project. Even though the code below seems to work (based on the response received), I am unable to lo ...

Display the $_SESSION data without refreshing the page when a button is clicked

I have an online cafe menu on my website where I add products to the shopping cart using AJAX requests. I want to display any changes made to $_SESSION every time there is an update (such as increasing or decreasing the quantity of products) without having ...

Creating an automated CRUD API using Node.js, Express, and Mongoose

In the realm of Python, we have often relied on tools like tastypie or Django-Rest-framework to build Rest APIs. After delving into Felix Geisendörfer's article Convincing the boss, one particular statement caught my attention: Node.js truly exce ...

Is there a way to implement a nested case statement in MySQL?

Consider the line provided in a select statement below: (case when p1 = 0 then 1 else (p2-p1)/p1 end) as delta_pct, This line calculates the percentage change between p1 and p2. If p1 is 0, it returns 1 to prevent a divide by zero error. However, if p2 is ...

"Enhancing partial views in Ruby on Rails: A step-by-step guide to

Seeking a method to update the partial view product_images.html.erb using ajax My js code is $("#delete-img").click(function(e){ var checkValues = $('input[name=image_id]:checked').map(function(){ return $(this).val(); ...

How can we increase the efficiency of calculating the total sum for various fields across multiple rows?

I am currently working with a MySQL subquery that selects multiple rows with 15 column names by joining two tables. One table contains 400,000 records while the other has 9,000 records. In this query, I am using unique IDs in both tables as filters and ap ...

Ways to block or inhibit the ability to traverse back using the browser's back button with react-router-dom v6

I am currently using react-router-dom version 6, and after looking at other people's questions without much luck, I need help with making it impossible to go back to any point. const App = () => { const user = useSelector((state) => state.user ...

The outcome of the Next.js query has not been explicitly provided

Currently, I am learning Next.js (TypeScript) and I have created the function getServerSideProps({query}) in detail/[slug].tsx. However, the query does not provide the expected result in the URL. For example, when the URL is localhost:3000/detail/samsung- ...

Retrieve data from server using Angular and present content on a dedicated webpage

I am currently working on a page that displays all usernames, and when I click on a username, I want to retrieve more information from the server and display it on a separate User page (including first name, last name, etc). However, I am encountering an ...

What is the reason behind the appearance of 'Cannot Get/' when trying to render pug?

Attempting to configure a basic Express server with a simple pug template. Could you kindly point out what I might be doing incorrectly in this setup? 'use strict'; //Require Express var express = require('express'); var app = expres ...

Newtonsoft date parsing issue causes date to be off by one day

I am encountering an issue in my TypeScript project where the date selected by users is not being parsed correctly. For example: (JSON) "IssueDate":"Wed Jan 18 2017 00:00:00 GMT+0200 (Jordan Standard Time)" However, when I try to parse the object using ...

Save the json data to a local storage using jQuery Mobile

Is there a way to save JSON data locally without relying on a specific URL, such as www.example.com/myjson.php The problem I'm facing is that my code functions properly only when it's uploaded and executed through a server For example: www.exam ...

"Can we trust the accuracy of the Reverse Bits Solution that Utilizes Left Shift Operations

Seeking a solution for reversing bits using left shift results, the problem involves reversing the bits of a given 32-bit unsigned integer. Input: n = 00000010100101000001111010011100 Output: 964176192 (00111001011110000010100101000000) Explanation: The ...

Attempting to fetch information from MySQL database in Laravel 5 for display

Currently, I am working on fetching data from a table in my MySQL database to display it using Laravel 5. Just to provide some context, I am using Vagrant with a Windows host machine and CentOS as my guest machine. I have already imported data into a MySQL ...

Creating unique validation rules using VeeValidate 3 and vue.js

I have a form where I need to establish specific rules. For instance, consider the following code snippet: <label class="form-label">Price range from</label> <validation-provider rules="required_if:price_to" name="Price range from" ...

Having trouble sending data from my useState hook to Mysql database

Struggling to send input data from useState to MySQL? It seems like a challenge when trying to post data using state hooks with multiple values. Your assistance would be greatly appreciated. Here is the code snippet for sending form data: import React,{us ...