ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Classic ASP如何解析AJAX提交的JSON数据

2026/9/2 4:53:54 拓冰建站 浏览量
Classic ASP如何解析AJAX提交的JSON数据 简介面向使用ASP开发动态Web应用的工程师本实例完整演示了在服务端接收AJAX请求并解析其中JSON数据的方法可应用于用户输入验证、数据更新、局部刷新等常见交互场景。资源压缩包仅19KB共6个文件包括4个ASP处理脚本、1个HTML触发页面及1个Access数据库ASP脚本涵盖客户端与服务器端两类HTML负责发起异步请求数据库用于持久化存储结构划分清晰。已有385人学习使用。实例重点讲解了借助ScriptControl对象调用JSON.parse()函数完成核心解析通过ADODB.Stream将收到的二进制流按UTF-8编码转换为字符串再使用For Each遍历解析后的对象、访问键值每段关键步骤均配有可复用的VBScript代码片段。读者学后可快速掌握ASP接收与解析AJAX提交的JSON数据的标准流程并能将相关代码直接迁移到实际项目按需增加错误处理与数据验证逻辑提升开发效率。 “接口返回正常但是我用AJAX传过去的JSON你那边怎么收不到Request.Form永远是空的。”这句话我听过不止一次而且每次都是从维护老ASP系统的同事嘴里说出来的。经典ASPClassic ASP本身没有内置JSON对象更不能像PHP的json_decode那样直接解析而AJAX提交JSON时只要Content-Type设成application/json数据就根本不会出现在Request.Form里。ASP解析AJAX提交的JSON数据核心就是一行一行把原始请求体读出来再按UTF-8解码成字符串最后交给类库或脚本解析成VBScript对象。这篇文章会从一个用户信息提交的完整实例出发把前端怎么写、后端怎么接、JSON怎么解析、中文怎么不乱码以及我实际排查过的问题都写清楚。正维护老ASP系统、又不得不对接新前端的朋友可以直接照着抄。1. 老ASP项目却被AJAX甩了一脸JSON问题从哪来1.1 事故现场为什么Request.Form是空的先说现场。前端同事用jQuery发请求代码大概是这样$.ajax({ url: save_user.asp, type: POST, contentType: application/json; charsetutf-8, data: JSON.stringify({ name: 张三, age: 30 }), success: function(res) { /* ... */ } });然后后端ASP里写的是name Request.Form(name) age Request.Form(age)看似天经地义但name和age全是空。原因并不玄乎Request.Form这个集合只能拿到application/x-www-form-urlencoded或multipart/form-data这两种格式提交的POST数据。当前端把Content-Type改成application/json之后JSON字符串是作为一个完整的请求体发到服务器IIS不会帮你把它拆成表单字段Request.Form自然就查无此物。这就好比快递明明送到门口了但你只去前台登记簿上找当然找不到。1.2 Classic ASP处理JSON的天然短板Classic ASP是VBScript脚本环境它没有JavaScript里那种原生的JSON.parse也没有PHP的json_decode。处理JSON字符串要么引入第三方类库要么自己写正则去抠字段。所以同样一个接口放在新版后端框架里可能三行代码就完事在ASP里你得先解决“请求体怎么读出来”的问题再解决“字符串怎么变成对象”的问题中间还夹着一个“编码怎么统一”的问题。这三个问题但凡有一个没处理好接口就表现为各种莫名其妙的空值、乱码、500错误。1.3 为什么不直接换技术栈而是打补丁说实话第一次遇到这个问题时我也想过干脆把这接口挪到新框架里。但现实是一个跑了好多年的ASP系统背后的数据库逻辑、权限体系、会话状态、文件上传都跟老代码缠在一起为了一个接收JSON的小功能去迁移整个项目风险太大。更务实的做法是在现有ASP站点里新开一个接口专门接收JSON请求业务处理完再返回JSON。这个“外科手术式”的补丁方案不需要动到其他老页面改完能立刻上线这也是这篇实例最适用的场景。2. AJAX提交JSON时数据到底放在哪了2.1 Content-Type是幕后导演要理解后端为什么取不到数据关键是搞清楚不同Content-Type下POST数据的去向。我对接前端时习惯先让同事把请求头截图发过来看Content-Type基本就能预判后端该怎么取。Content-Type请求体格式后端怎么拿application/x-www-form-urlencodedkeyvaluekey2value2Request.Form(key)multipart/form-data按boundary分段的表单数据Request.Form、Request.BinaryReadapplication/json原始JSON字符串只能Request.BinaryRead很多人写AJAX时没有主动设置Content-TypejQuery默认会用application/x-www-form-urlencoded这时候如果你把JSON字符串塞给data后端Request.Form(data)其实能拿到但拿到的是一个字符串还得再解析一次。真正标准、规范的JSON提交方式是把Content-Type设为application/json数据原样进入请求体。这两种方式我都接过但后面这套实例只讲标准方式因为这种方式更通用也不容易被URL编码各种转义问题坑到。2.2 三种前端写法的实际效果除了jQuery原生XMLHttpRequest和fetch提交JSON也是常见操作。这里给出三种写法它们后端拿数据的方式完全一样// 方式一jQuery $.ajax({ url: save_user.asp, type: POST, contentType: application/json; charsetutf-8, data: JSON.stringify({ name: 张三, age: 30 }) }); // 方式二原生XMLHttpRequest var xhr new XMLHttpRequest(); xhr.open(POST, save_user.asp, true); xhr.setRequestHeader(Content-Type, application/json; charsetutf-8); xhr.send(JSON.stringify({ name: 张三, age: 30 })); // 方式三fetch fetch(save_user.asp, { method: POST, headers: { Content-Type: application/json; charsetutf-8 }, body: JSON.stringify({ name: 张三, age: 30 }) });用JSON.stringify序列化出来的结果是一个标准的JSON字符串浏览器在发送时会把字符串按UTF-8编码成字节流放到HTTP请求的消息体里。后端ASP要做的就是把这段字节流读出来再按UTF-8解码成原来的JSON字符串。2.3 请求体长什么样后端面对的是什么用F12打开浏览器开发者工具切到Network面板找到save_user.asp这条请求看Payload或者请求体会看到类似这样的内容{name:张三,age:30}这就是后端面对的全部数据。它不是一个一个分开的字段而是一整段字符串。ASP脚本拿到这段字符串之后要用JSON解析器把它拆成name、age等独立的值。所以在写后端逻辑时第一步不是Request.Form而是“把请求体完整读出来”。这一步走对了后面的解析才有意义。3. 后端取数据从Request.Form到BinaryRead的转换3.1 读取原始请求体的标准姿势经典ASP里读取原始请求体用的是Request.BinaryRead(Request.TotalBytes)。Request.TotalBytes是请求体的字节数BinaryRead返回一个字节数组也就是原始的二进制数据。因为我们的JSON是UTF-8编码的所以还需要把字节数组转成UTF-8字符串。这里最常用的办法是借助ADODB.Stream组件它相当于一个内存里的文件流先把二进制写进去再指定字符集读出来。% Option Explicit Response.CodePage 65001 Response.Charset utf-8 Dim requestBody If Request.TotalBytes 0 Then requestBody BytesToUTF8(Request.BinaryRead(Request.TotalBytes)) Else requestBody End If Function BytesToUTF8(bytes) Dim stream Set stream Server.CreateObject(ADODB.Stream) stream.Type 1 adTypeBinary stream.Open stream.Write bytes stream.Position 0 stream.Type 2 adTypeText stream.Charset utf-8 BytesToUTF8 stream.ReadText stream.Close Set stream Nothing End Function %这段代码几乎可以原样复用。stream.Type 1表示写入二进制写入完成后把指针挪到开头再改成文本模式并指定utf-8字符集最后用ReadText把整个内容读成字符串。这一套下来后端拿到的requestBody就应该和前端发送的JSON字符串完全一致。3.2 为什么Request.TotalBytes判断必不可少很多人第一版代码没写If Request.TotalBytes 0 Then结果请求体为空时Request.BinaryRead(0)直接报错。因为BinaryRead需要读取具体字节数传0进去其实是非法操作。先判断TotalBytes是否大于0既避免空请求体的异常也让你能区分“请求来了但没带JSON”和“请求根本没到后端”这两种情况。调试接口时可以先把requestBody原样输出到页面如果页面空白但TotalBytes大于0说明读取函数有问题如果TotalBytes就是0那问题大概率出在请求本身没送达不用在解析代码上浪费时间。3.3 编码统一三个地方都要对上中文乱码是这一类接口最常见的坑。只要“前端编码、后端解码、页面输出”三个环节有一个不一致中文就会变成“锟斤拷”或者问号。按我的经验最终能稳定不乱码的配置是第一前端Content-Type里带上charsetutf-8第二ASP页面文件本身以UTF-8格式保存第三页面顶部设置Response.CodePage 65001和Response.Charset utf-8。这三件事看起来简单但实际项目里经常遇到页面文件是ANSI保存的或者CodePage忘了写结果接口返回给前端的中文全乱。排查顺序我建议是先看请求体解码出来的字符串是否正常再管输出编码两个问题分开验证不要混在一起。3.4 老服务器上ADODB.Stream不可用的备用思路大多数Windows服务器上的IIS都带ADODB.Stream组件但有些卖家部署的安全策略或者精简组件的老环境会禁用这个对象。遇到Server.CreateObject失败时可以改用.NET的System.Text.Encoding来转码不过VBScript里调用.NET对象不算方便我实际项目中还是优先确认组件是否可用。还有一个更笨但稳妥的替代方案是让前端直接把JSON用URL编码后塞进Request.Form(data)后端拿字符串后先URLDecode再解析。这等于绕开了BinaryRead虽然不够“标准”但胜在兼容性极好。真到万不得已时这招可以救急。4. JSON字符串变成VBScript对象三种解析思路4.1 先用现成类库aspJSON经典ASP解析JSON我最推荐的是开源类库aspJSONGitHub上搜rcdmk/aspJSON核心文件就是json.asp。把json.asp放到站点目录然后在处理页面里include进来实例化类后调loadJSON方法即可。它会把JSON对象解析成VBScript里的Scripting.Dictionary数组则解析成集合用起来很顺手。!-- #include filejson.asp -- % Dim oJSON Set oJSON New aspJSON oJSON.loadJSON requestBody Response.Write oJSON.data(name) Response.Write oJSON.data(age) %如果JSON里有嵌套数组比如tags: [admin, vip]访问方式大概是遍历oJSON.data(tags)这个集合。类库的好处是帮你处理了引号、冒号、逗号、转义字符这些琐碎细节你不用自己维护解析逻辑。用之前一定要确保json.asp文件跟当前ASP页面在同一个目录或者include路径写对否则会直接报“未找到包含文件”的错误。4.2 手写一个简单解析器但要有边界感如果不想引入外部文件或者业务场景非常简单也可以用VBScript的正则表达式做一个简易提取函数。比如只取某个字符串字段的值Function GetJsonValue(jsonText, key) Dim regEx, match Set regEx New RegExp regEx.IgnoreCase True regEx.Pattern key \s*:\s*([^]*) Set match regEx.Execute(jsonText) If match.Count 0 Then GetJsonValue match(0).SubMatches(0) Else GetJsonValue End If End Function调用方式就是GetJsonValue(requestBody, name)。但这里必须说清楚这个正则只适合提取“字符串类型的值”碰到数字、布尔值、嵌套对象、数组就抓瞎。我之前在一个内部小工具里用过类似写法后来前端多传了一个tags数组解析结果直接不对。所以我的建议是手写解析器只适合“接口永远不变、数据结构极其简单”的临时场景正式接口还是用类库省心得多。4.3 解析之后的数据类型转换和容错即便用了aspJSON从JSON里读出来的值也未必是你想要的VBScript类型。比如JSON数字age: 30解析后VBScript可能当成字符串要算年龄加1就得CLng转一下JSON布尔值true解析后可能是true需要自己判断。我习惯封装几个小函数JsonToInt(val)、JsonToBool(val)在读取字段时就统一转换。另外访问字典里不存在的键会触发运行时错误最好先用On Error Resume Next包裹解析和字段读取拿到Err.Number后就返回友好错误信息否则用户一旦提交缺字段的JSON接口就是一个500白屏。4.4 一个容易被忽略的BOM问题还有一种情况我排查了挺久解析函数明明没问题但loadJSON一执行就报错把JSON字符串打印出来看开头有个看不见的?字符。这其实是UTF-8的BOMByte Order Mark被ADODB.Stream解码后带进了字符串。解决方式很简单解析前先判断开头是不是ChrW(HFEFF)是的话就裁掉。虽然并不是每次都会出现但只要你的编辑器或者某些代理工具在请求体前塞了BOM解析就会失败。这个坑很隐蔽排查时如果总在解析函数上卡住记得先看字符串最前面有没有多余字符。5. 完整实例用户信息提交接口与真实踩坑排查5.1 前端页面代码这里给一个可以直接测试的完整页面包含姓名、年龄、标签三个字段提交时用AJAX将整个对象序列化成JSON发给后端。!DOCTYPE html html langzh-CN head meta charsetUTF-8 title用户信息提交/title script srchttps://code.jquery.com/jquery-3.6.0.min.js/script /head body form iduserForm input typetext namename idname value张三 input typetext nameage idage value30 input typetext nametags idtags valueadmin,vip button typebutton idsubmitBtn提交/button /form script $(#submitBtn).on(click, function () { var tags $(#tags).val().split(,); $.ajax({ url: save_user.asp, type: POST, contentType: application/json; charsetutf-8, dataType: json, data: JSON.stringify({ name: $(#name).val(), age: parseInt($(#age).val(), 10), tags: tags }) }).done(function (res) { if (res.code 0) { alert(提交成功 res.data.name); } else { alert(提交失败 res.message); } }).fail(function () { alert(请求失败); }); }); /script /body /html这个页面里最关键的还是contentType: application/json; charsetutf-8和JSON.stringify。如果你不小心把data直接写成普通对象而不是字符串化结果jQuery会按表单格式序列化后端接收方式又不一样了所以这两个点必须保持一致。5.2 ASP后端完整处理代码后端页面save_user.asp的完整代码大概长这样。注意这里引用了json.asp实际部署时确保文件存在。!-- #include filejson.asp -- % Option Explicit Response.CodePage 65001 Response.Charset utf-8 Dim requestBody If Request.TotalBytes 0 Then requestBody BytesToUTF8(Request.BinaryRead(Request.TotalBytes)) Else requestBody End If Dim oJSON Set oJSON New aspJSON On Error Resume Next oJSON.loadJSON requestBody If Err.Number 0 Then Response.ContentType application/json Response.Write {code:500,message:json解析失败} Response.End End If On Error GoTo 0 Dim sName, sAge, sTagList, tag sName oJSON.data(name) sAge oJSON.data(age) sTagList For Each tag In oJSON.data(tags) If sTagList Then sTagList sTagList , sTagList sTagList tag Next 这里可以接数据库逻辑注意用参数化查询 略... Response.ContentType application/json Response.Write {code:0,message:ok,data:{name: sName ,age: sAge ,tags: sTagList }} Function BytesToUTF8(bytes) Dim stream Set stream Server.CreateObject(ADODB.Stream) stream.Type 1 stream.Open stream.Write bytes stream.Position 0 stream.Type 2 stream.Charset utf-8 BytesToUTF8 stream.ReadText stream.Close Set stream Nothing End Function %代码里我故意用On Error Resume Next包了解析过程这是为了不让非法JSON直接把页面打崩。返回的JSON由字符串拼接而成虽然简单但字段值里如果有双引号或反斜杠就需要额外转义所以在实际项目中我更推荐用类库自带的方法把VBScript字典序列化成JSON避免手拼出错。5.3 排查链路从空请求体到中文乱码再到解析报错如果你照着写还是出问题按下面这个链路走基本能定位到根因。打开F12的Network面板找到请求确认请求头里的Content-Type确实是application/json。这一步能筛掉一半“Request.Form取不到”的问题。在后端代码最前面临时输出Request.TotalBytes。如果返回0说明请求体根本没到ASP需要检查URL是否被重定向、IIS是否有请求筛选模块拦截或者前端请求地址写错。把requestBody原样输出到页面先看字符串本身对不对。如果此处乱码优先检查ADODB.Stream的Charset是否为utf-8、页面文件是否以UTF-8保存、Response.CodePage是否65001。在调用loadJSON前检查字符串开头是否有BOM字符有就去掉。解析报错时把完整的JSON文本贴到JSON校验工具里确认格式合法。很多时候是前端拼接出了多余的逗号或单引号ASP解析器可没浏览器那么宽容。我遇到的最多情况其实是前两步没排查清楚后端一直在跟解析函数较劲。先把数据流确认了再谈解析效率会高很多。5.4 安全校验放在解析前还是解析后最后说安全。既然接口能接收任意JSON那就要做好面对脏数据的准备。我的习惯是两层都做解析前先判断Request.TotalBytes的大小超过合理阈值直接拒绝避免有人往接口灌超大请求体再判断Content-Type里是否包含application/json不是就直接返回错误。解析后对每个字段做类型和长度校验比如age必须能转成数字name长度不能超过50tags最多10个。这里特别提醒一句无论解析出来的是什么都不要直接拼进SQL字符串。ASP老项目里SQL注入最常见的就是这种“看似无害的接口”把name当成字符串拼进SELECT或INSERT一旦被人塞了恶意内容后果很严重。正确做法是用ADODB.Command加参数化查询或者至少把单引号替换掉再入库。做完这个接口之后我最大的体会是ASP解析AJAX提交的JSON难的不是JSON解析本身而是数据链路太长前端序列化、请求头设置、后端读流、解码、解析、输出编码任何一环脱节都会让你误以为“解析函数写得不对”。所以排查时一定要按数据流一步步验证先保证原始字符串拿到了再谈下一步。这个小习惯比任何类库都管用。本文还有配套的精品资源点击获取