XML名称不能以'%'开头字符

时间:2017-02-08 19:25:57

标签: javascript jquery post url-encoding

我试图使用jQuery将XML发布到Web服务。我收到的回复是我没想到的:

"名称不能以'%'开头字符,十六进制值0x25。第1行,第65位。"

代码

$(function() {
    var xmlStr = '<?xml version="1.0" encoding="utf-8" ?><TransactionSetup xmlns="obsfucated"><Credentials><AccountID>1043155</AccountID><AccountToken>obsfucated</AccountToken><AcceptorID>obsfucated</AcceptorID></Credentials><Application><ApplicationID>obsfucated</ApplicationID><ApplicationVersion>1.0</ApplicationVersion><ApplicationName>Test</ApplicationName></Application><Terminal><TerminalID>01</TerminalID><CardholderPresentCode>2</CardholderPresentCode><CardInputCode>5</CardInputCode><TerminalCapabilityCode>3</TerminalCapabilityCode><TerminalEnvironmentCode>2</TerminalEnvironmentCode><CardPresentCode>2</CardPresentCode><MotoECICode>1</MotoECICode><CVVPresenceCode>1</CVVPresenceCode></Terminal><Transaction><TransactionAmount>SPI_CartTotalFinal</TransactionAmount></Transaction><TransactionSetup><TransactionSetupMethod>1</TransactionSetupMethod><Embedded>1</Embedded><AutoReturn>1</AutoReturn><ReturnURL>Obsfucated</ReturnURL><CustomCss>body{margin-left:50px;font-family:arial;font-size:large;border:none;}</CustomCss></TransactionSetup></TransactionSetup>',
        guid;
    $.ajax({
        type: 'POST',
        url: 'webserviceurl',
        contentType: "text/xml",
        dataType: "xml",
        data: {
            Action: $('#Action').val(),
            IsAjax: $('#IsAjax').val(),
            xml: xmlStr,
        },
        success: function(response) {
            guid = response;
            console.log('success' + guid);
        },
        error: function (jqXHR, tranStatus, errorThrown) {
        console.log(
            'Status: ' + jqXHR.status + ' ' + jqXHR.statusText + '. ' +
            'Response: ' + jqXHR.responseText
        );
    }
    });

更新 - 发布数据

<TransactionSetup xmlns="https://www.obsfucated.com"%3E%20%3CCredentials%3E%20%3CAccountID%3E1223135%3C/AccountID%3E%20%3CAccountToken%3EA9A22221CBE222ED0E287D6F34B0222E0F928E4DDF6C37B945CE05F78054DF95966FC201%3C/AccountToken%3E%20%3CAcceptorID%322228907%3C/AcceptorID%3E%20%3C/Credentials%3E%20%3CApplication%3E%20%3CApplicationID%3E8003%3C/ApplicationID%3E%20%3CApplicationVersion%3E1.0%3C/ApplicationVersion%3E%20%3CApplicationName%3EHostedPayments.CSharp%3C/ApplicationName%3E%20%3C/Application%3E%20%3CTerminal%3E%20%3CTerminalID%3E01%3C/TerminalID%3E%20%3CCardholderPresentCode%3E2%3C/CardholderPresentCode%3E%20%3CCardInputCode%3E5%3C/CardInputCode%3E%20%3CTerminalCapabilityCode%3E3%3C/TerminalCapabilityCode%3E%20%3CTerminalEnvironmentCode%3E2%3C/TerminalEnvironmentCode%3E%20%3CCardPresentCode%3E2%3C/CardPresentCode%3E%20%3CMotoECICode%3E1%3C/MotoECICode%3E%20%3CCVVPresenceCode%3E1%3C/CVVPresenceCode%3E%20%3C/Terminal%3E%20%3CTransaction%3E%20%3CTransactionAmount%3E0.20%3C/TransactionAmount%3E%20%3C/Transaction%3E%20%3CTransactionSetup%3E%20%3CTransactionSetupMethod%3E1%3C/TransactionSetupMethod%3E%20%3CEmbedded%3E1%3C/Embedded%3E%20%3CAutoReturn%3E1%3C/AutoReturn%3E%20%3CReturnURL%3Ehttp://shop.masterssupply.net/webcattest/WebCatPageServer.exe%3C/ReturnURL%3E%20%3CCustomCss%3E%20.tdHeader%20{%20%20%20%20%20background-color:%20%23F8F8F8;%20%20%20%20%20padding:%205px;%20%20%20%20%20font-weight:%20bold;%20}%20.tdLabel%20{%20%20%20%20%20font-weight:%20bold;%20%20%20%20%20text-align:%20right;%20%20%20%20%20padding-right:%2010px;%20%20%20%20%20padding-left:%2010px;%20%20%20%20%20padding-top:%2010px;%20%20%20%20%20padding-bottom:%2010px;%20}%20.tdField%20{%20%20%20%20%20padding-right:%2010px;%20%20%20%20%20padding-left:%2010px;%20%20%20%20%20padding-top:%2010px;%20%20%20%20%20padding-bottom:%2010px;%20}%20.content%20{%20%20%20%20%20padding-left:%2010px;%20%20%20%20%20padding-top:%205px;%20%20%20%20%20padding-bottom:%205px;%20%20%20%20%20border-left-style:%20none;%20%20%20%20%20border-left-width:%20none;%20%20%20%20%20border-left-color:%20none;%20%20%20%20%20border-right-style:%20none;%20%20%20%20%20border-right-width:%20none;%20%20%20%20%20border-right-color:%20none;%20}%20.tdTransactionButtons%20{%20%20%20%20%20text-align:%20left;%20%20%20%20%20padding-top:%205px;%20%20%20%20%20height:%2035px;%20%20%20%20%20border-top-style:%20none;%20%20%20%20%20border-top-width:%20none;%20%20%20%20%20border-top-color:%20none;%20%20%20%20%20vertical-align:%20middle;%20}%20body%20{%20%20%20%20%20margin-left:%20none;%20%20%20%20%20font-family:%20arial;%20%20%20%20%20font-size:%2012px;%20%20%20%20%20border:%20none;%20}%20.buttonEmbedded:link%20{%20%20%20%20%20font-size:%2013px;%20%20%20%20%20font-weight:%20bold;%20%20%20%20%20padding-right:%2010px;%20%20%20%20%20padding-left:%2010px;%20%20%20%20%20padding-top:%204px;%20%20%20%20%20padding-bottom:%204px;%20%20%20%20%20border:%204px%20solid%20%23ce701a;%20%20%20%20%20color:%20%23ffffff;%20%20%20%20%20background-color:%20%23ce701a;%20%20%20%20%20text-decoration:%20none;%20%20%20%20%20border-top-style:%20solid;%20%20%20%20%20border-top-width:%201px;%20%20%20%20%20border-top-color:%20%23ce701a;%20%20%20%20%20border-right-color:%20%23ce701a;%20%20%20%20%20border-left-color:%20%23ce701a;%20%20%20%20%20border-bottom-color:%20%23ce701a;%20}%20.buttonCancel{%20%20%20%20%20border:%201px%20solid%20%23444;%20%20%20%20%20font-weight:%20bold;%20%20%20%20%20color:%20%23fff;%20%20%20%20%20border:%201px%20solid%20%23444;%20%20%20%20%20background-color:%20%237c7c7c;%20%20%20%20%20box-shadow:%20none;%20%20%20%20%20border-radius:%200px;%20%20%20%20%20padding:%206px%2012px;%20%20%20%20%20font-size:%2014px;%20%20%20%20%20line-height:%204.428571;%20%20%20%20%20text-decoration:%20none;%20%20%20%20%20padding-right:%2010px;%20%20%20%20%20padding-left:%2010px;%20%20%20%20%20padding-top:%204px;%20%20%20%20%20padding-bottom:%204px;%20%20%20%20%20border-top-style:%20solid;%20%20%20%20%20border-top-width:%201px;%20%20%20%20%20border-top-color:%20%23838383;%20%20%20%20%20border-right-color:%20%23838383;%20%20%20%20%20border-left-color:%20%23838383;%20%20%20%20%20border-bottom-color:%20%23838383;%20}%20.buttonCancel:link%20{%20%20%20%20%20color:%20%23fff;%20}%20.buttonCancel:visited%20{%20%20%20%20%20color:%20%23fff;%20}%20%3C/CustomCss%3E%20%3C/TransactionSetup%3E%20%3C/TransactionSetup%3E%20

正如您所看到的,数据是经过网址编码的。我认为问题出在哪里,但我不知道如何修复它。任何指导都会有所帮助。谢谢!

4 个答案:

答案 0 :(得分:4)

我看了一下代码,发现了一些问题需要研究。

  1. 您发布的功能代码缺少结束'});'适当地关闭函数和ajax调用。这可能只是由于您发布问题时的复制粘贴问题。但是,要明确。需要使用以下代码块才能使其正常工作。

    $(function() {
        var xmlStr = 'validxml', guid;
    
        $.ajax({
            option1:"option1"
        });
    //basically, this last closing bracket/paren was missing in the sample code
    });
    
  2. 您发布的XML似乎无效。有一个开头<TransactionSetup>标记,但最后似乎有两个关闭</TransactionSetup>标记。这很可能不会导致jQuery如何发布数据的问题,但是当它需要反序列化XML时,它可能会导致服务器端的问题。

  3. 您显示为已过帐的数据很奇怪,原因有两个。首先,它不包括javascript变量显示开头的XML序言。 (相反,它只是以<TransactionSetup>开头。其次,编码是奇怪的,因为看起来xmlns属性之后的事情正在编码但之前没有。我认为基于错误消息的问题来源是服务器在解析XML时非常困难,因为它在开始时没有编码,然后突然变成编码部分。这是有道理的,基于错误消息“名称不能以'%'字符开头”,因为它遇到了XML中编码的尖括号,当它不期望时。

  4. 我的建议是:

    1. 验证所有右括号/括号是否正确
    2. 验证XML是否全部有效(正确打开和匹配结束标记)
    3. 然后开始排除问题,如果它仍然存在的话。我建议改变的第一件事就是完全从ajax()调用中删除contentType:“text / xml”选项,因为在我的经验中发布XML时通常不需要设置或更改。我的猜测是,如果您删除该选项,您将更接近于确定问题。如果删除它没有帮助,请尝试将其更改为contentType:“application / xml”。

答案 1 :(得分:3)

您是否尝试过发送XML document而不是string

    data: {
        Action: $('#Action').val(),
        IsAjax: $('#IsAjax').val(),
        xml: $.parseXML(xmlStr),
    }

答案 2 :(得分:2)

错误是由于结尾前的空格而产生的?标志如下所示

<?xml version="1.0" encoding="utf-8" ?>

您可以使用代码段中提供的方式检查您的xml字符串并将其返回整洁

&#13;
&#13;
var xmlString ='<?xml version=\"1.0\" encoding=\"utf-8\" ?><TransactionSetup xmlns=\"obsfucated\"><Credentials><AccountID>1043155</AccountID><AccountToken>obsfucated</AccountToken><AcceptorID>obsfucated</AcceptorID></Credentials><Application><ApplicationID>obsfucated</ApplicationID><ApplicationVersion>1.0</ApplicationVersion><ApplicationName>Test</ApplicationName></Application><Terminal><TerminalID>01</TerminalID><CardholderPresentCode>2</CardholderPresentCode><CardInputCode>5</CardInputCode><TerminalCapabilityCode>3</TerminalCapabilityCode><TerminalEnvironmentCode>2</TerminalEnvironmentCode><CardPresentCode>2</CardPresentCode><MotoECICode>1</MotoECICode><CVVPresenceCode>1</CVVPresenceCode></Terminal><Transaction><TransactionAmount>SPI_CartTotalFinal</TransactionAmount></Transaction><TransactionSetup><TransactionSetupMethod>1</TransactionSetupMethod><Embedded>1</Embedded><AutoReturn>1</AutoReturn><ReturnURL>Obsfucated</ReturnURL><CustomCss>body{margin-left:50px;font-family:arial;font-size:large;border:none;}</CustomCss></TransactionSetup></TransactionSetup>';
var xmlDoc = $.parseXML( xmlString );
var newxmlString = (new XMLSerializer()).serializeToString(xmlDoc);
console.log([xmlString,newxmlString]);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
&#13;
&#13;
&#13;

之前和之后XML字符串的差异

enter image description here

修改

仔细查看发布的代码并修复丢失的})部分后,我会说你的问题是contentType被错误地声明。

为了更好地解释,您应该将contentType声明为text/plain,因为我认为它会回归到默认application/x-www-form-urlencoded。在jquery ajax文档中查看指定了

的contentType
  

注意:对于跨域请求,请将内容类型设置为任何内容   除了application/x-www-form-urlencodedmultipart/form-data或   text/plain会触发浏览器发送预检OPTIONS   请求服务器。

此外:

请查看关于content-Type的{​​{3}},并在SO中查看此HTTP access control (CORS)

初始代码

$(function() {
    var xmlStr = '<?xml version="1.0" encoding="utf-8" ?><TransactionSetup xmlns="obsfucated"><Credentials><AccountID>1043155</AccountID><AccountToken>obsfucated</AccountToken><AcceptorID>obsfucated</AcceptorID></Credentials><Application><ApplicationID>obsfucated</ApplicationID><ApplicationVersion>1.0</ApplicationVersion><ApplicationName>Test</ApplicationName></Application><Terminal><TerminalID>01</TerminalID><CardholderPresentCode>2</CardholderPresentCode><CardInputCode>5</CardInputCode><TerminalCapabilityCode>3</TerminalCapabilityCode><TerminalEnvironmentCode>2</TerminalEnvironmentCode><CardPresentCode>2</CardPresentCode><MotoECICode>1</MotoECICode><CVVPresenceCode>1</CVVPresenceCode></Terminal><Transaction><TransactionAmount>SPI_CartTotalFinal</TransactionAmount></Transaction><TransactionSetup><TransactionSetupMethod>1</TransactionSetupMethod><Embedded>1</Embedded><AutoReturn>1</AutoReturn><ReturnURL>Obsfucated</ReturnURL><CustomCss>body{margin-left:50px;font-family:arial;font-size:large;border:none;}</CustomCss></TransactionSetup></TransactionSetup>',
        guid;
    $.ajax({
        type: 'POST',
        url: 'webserviceurl',
        contentType: "text/xml",
        dataType: "xml",
        data: {
            Action: $('#Action').val(),
            IsAjax: $('#IsAjax').val(),
            xml: xmlStr,
        },
        success: function(response) {
            guid = response;
            console.log('success' + guid);
        },
        error: function (jqXHR, tranStatus, errorThrown) {
        console.log('Status: ' + jqXHR.status + ' '+jqXHR.statusText+'. '+'Response: '+jqXHR.responseText);
        }
    });
});

建议代码

$(function() {
var xmlStr = '<?xml version=\"1.0\" encoding=\"utf-8\"?><TransactionSetup xmlns=\"obsfucated\"><Credentials><AccountID>1043155</AccountID><AccountToken>obsfucated</AccountToken><AcceptorID>obsfucated</AcceptorID></Credentials><Application><ApplicationID>obsfucated</ApplicationID><ApplicationVersion>1.0</ApplicationVersion><ApplicationName>Test</ApplicationName></Application><Terminal><TerminalID>01</TerminalID><CardholderPresentCode>2</CardholderPresentCode><CardInputCode>5</CardInputCode><TerminalCapabilityCode>3</TerminalCapabilityCode><TerminalEnvironmentCode>2</TerminalEnvironmentCode><CardPresentCode>2</CardPresentCode><MotoECICode>1</MotoECICode><CVVPresenceCode>1</CVVPresenceCode></Terminal><Transaction><TransactionAmount>SPI_CartTotalFinal</TransactionAmount></Transaction><TransactionSetup><TransactionSetupMethod>1</TransactionSetupMethod><Embedded>1</Embedded><AutoReturn>1</AutoReturn><ReturnURL>Obsfucated</ReturnURL><CustomCss>body{margin-left:50px;font-family:arial;font-size:large;border:none;}</CustomCss></TransactionSetup></TransactionSetup>',
guid;       
var jqxhr = $.ajax({
        type: "POST",
        url: "webserviceurl",
        contentType: "text/plain",
        dataType: "xml",
        data: {
            Action: $('#Action').val(),
            IsAjax: $('#IsAjax').val(),
            xml: xmlStr,
        }
})
.done(function(data) {
    guid = data;
    console.log(data.responseXML);      
})
.fail(function( jqXHR, textStatus,errorThrown ) {
    console.log("Request failed: "+errorThrown+" - "+textStatus);
}); 
});

答案 3 :(得分:1)

发布的数据实际上不是xml,它是具有xml属性的对象。因此, contentType:&#34; text / xml&#34; 设置不适合您的ajax请求。

默认情况下,数据作为对象传入数据(技术上,除了字符串以外的任何东西) 将被处理并转换为查询字符串,适合默认的内容类型 &#34;应用程序/ X WWW的窗体-urlencoded&#34 ;.为防止以url编码格式发送数据,您可以 考虑将您发布的数据转换为json字符串,并将 contentType 设置更改为 的&#34;应用/ JSON;字符集= UTF-8&#34;

$(function() {
    var xmlStr = '<?xml version="1.0" encoding="utf-8" ?><TransactionSetup xmlns="obsfucated"><Credentials><AccountID>1043155</AccountID><AccountToken>obsfucated</AccountToken><AcceptorID>obsfucated</AcceptorID></Credentials><Application><ApplicationID>obsfucated</ApplicationID><ApplicationVersion>1.0</ApplicationVersion><ApplicationName>Test</ApplicationName></Application><Terminal><TerminalID>01</TerminalID><CardholderPresentCode>2</CardholderPresentCode><CardInputCode>5</CardInputCode><TerminalCapabilityCode>3</TerminalCapabilityCode><TerminalEnvironmentCode>2</TerminalEnvironmentCode><CardPresentCode>2</CardPresentCode><MotoECICode>1</MotoECICode><CVVPresenceCode>1</CVVPresenceCode></Terminal><Transaction><TransactionAmount>SPI_CartTotalFinal</TransactionAmount></Transaction><TransactionSetup><TransactionSetupMethod>1</TransactionSetupMethod><Embedded>1</Embedded><AutoReturn>1</AutoReturn><ReturnURL>Obsfucated</ReturnURL><CustomCss>body{margin-left:50px;font-family:arial;font-size:large;border:none;}</CustomCss></TransactionSetup></TransactionSetup>',
        guid;
    $.ajax({
        type: 'POST',
        url: 'webserviceurl',
        contentType: "application/json; charset=utf-8",
        dataType: "xml",
        data: JSON.stringify({
            Action: $('#Action').val(),
            IsAjax: $('#IsAjax').val(),
            xml: xmlStr,
        }),
        success: function(response) {
            guid = response;
            console.log('success' + guid);
        },
        error: function (jqXHR, tranStatus, errorThrown) {
        console.log(
            'Status: ' + jqXHR.status + ' ' + jqXHR.statusText + '. ' +
            'Response: ' + jqXHR.responseText
        );
    }
    });

我已在此链接https://jsfiddle.net/b6f4tuyx/1/创建了一个示例,您可以查看它。