VisualForce에서 rerender하면 4 바이트 문자가 깨집니다.

문제점



SalesForce의 VisualForce에서 rerender하면
4바이트 문자가 깨진

샘플



단순히 버튼 누르면 다시 그릴 뿐인 화면을 작성

Test.vfp

<apex:page standardController="User" extensions="TestController" title="Test">
    <div>rerender範囲外:𠮷野家</div>
    <apex:form id="frm">
        <div>rerender範囲内:𠮷野家</div>
        <apex:commandButton value="rerender" action="{!act}" status="reloadStatus" rerender="frm" />
    </apex:form>
</apex:page>


TestController.apxc

public class TestController {
    public TestController(ApexPages.StandardController controller) {

    }

    public void act(){
        return;
    }
}

이제 rerender 버튼을 누르면




rerender 범위내의 「 𠮷野家 」가 「 ஷ野家 」가 되어 버린다
※범위외에 관해서는 변경 없음

조사



문자 코드



우선 「 𠮷 」와 「 」의 코드 포인트 조사했다

Test.js

console.log(''.codePointAt().toString(16));    // 0x0bb7
console.log('𠮷'.codePointAt().toString(16));    // 0x20bb7


절대 이것
사로 게이트 쌍 문자 (4 바이트 문자)가 이상해지는 모양

누락 지점


rerender 의 범위외는 정상이기 때문에 apex:commandButton버튼을 누르면 Ajax에서 Apex에 액세스하는 것처럼 응답 내용을 살펴보십시오.

Response

<?xml version="1.0"?>
<html lang="en_US" xmlns="http://www.w3.org/1999/xhtml"><head>
    <!--省略-->
</head>
<body>
    <form id="j_id0:frm" name="j_id0:frm" method="post" action="https://hogehoge.visual.force.com/apex/Test?core.apexpages.request.devconsole=1" enctype="application/x-www-form-urlencoded">
        <input type="hidden" name="j_id0:frm" value="j_id0:frm" /> 
        <div>rerender範囲内:ஷ野家</div>
    <!--省略-->
</body>
</html>


이미 괴롭히다
이건 보는 한 XML에서는 사로 게이트 페어 사용할 수없는 것 같습니다.

수치 문자 참조 &#x20bb7; 로 하면 좋을까~
상황 변함없이 Ajax의 응답 시점에서 깨져 있었다.

대책



고통의 수단으로 이스케이프를 끼우기로 결정했습니다.
화면 측에서 디코딩 할 수 있다면 URL 인코딩이나 다른 것이 좋다고 생각합니다.

Test.vfp

<apex:page standardController="User" extensions="TestController" title="Test">
    <div>rerender範囲外:𠮷野家</div>
    <apex:form id="frm">
        <div id="yoshi" style="visibility:hidden;">%uD842%uDFB7</div>
        <apex:commandButton value="rerender" action="{!act}" status="reloadStatus" rerender="frm" />
        <script>
            var ysdiv = document.getElementById('yoshi')
            ysdiv.innerHTML = unescape(ysdiv.innerHTML);
            ysdiv.style.visibility = "visible";
        </script>
    </apex:form>
</apex:page>


이스케이프 후 문자열을 표시하고 JS에서 억지로 되돌리는 느낌<script>rerender 안에 두지 않으면 움직이지 않으므로 주의

깨끗한 대책을 원합니다.

좋은 웹페이지 즐겨찾기