JavaScript__脚本化HTTP的练习题

一、选择题
1.规定Web浏览器如何从Web服务器获取文档的协议是( )
A. HTTP
B. FTP
C. Mailto
D. gopher

2.Comet不是下面的哪个选项?( )
A. 服务器推
B. Ajax推
C. HTTP流
D. Ajax

3.关于JSONP,表述错误的是?( )
A. 脚本通过设置<img>元素的src属性,并经过编码传输给服务器

B. 设置<iframe>的src属性为该URL。服务器能创建一个包含响应内容的HTML文档
C. <script>元素的src属性能设置URL并发起HTTP GET请求

D. 通过XMLHttpRequest对象,使用脚本来操纵HTTP

4.不属于HTTP请求的是?( )
A. HTTP请求方法或“动作”
B. 正在请求的URL
C.可选的请求头集合,包括身份验证信息
D. response响应头

5.不属于HTTP请求的是?( )
A. HTTP请求方法或“动作”
B. 正在请求的URL
C.可选的请求头集合,包括身份验证信息
D. response响应头

6.不属于HTTP请求的是?( )
A. HTTP请求方法或“动作”
B. 正在请求的URL
C.可选的请求头集合,包括身份验证信息
D. response响应头

7.关于request的open方法,表述错误的是( )
A. 第一个参数指定HTTP方法或动作
B. 方法不包括“DELETE”和“HEAD”
C. 第2个参数是URL,它是请求的主题
D. 设置请求头

8.关于HTTP响应,表述错误的是?( )
A. 以数字和文本的形式返回HTTP状态码

B. 使用getResponseHeader()和getAllResponseHeaders()能查询响应头
C. 从responseText属性中得到文本形式的响应主体

D. 从responseXML属性中得到XML形式的响应主体

9.关于XMLHttpRequest对象的responseText属性,不属于它的MIME类型的是( )
A. “text/plain”
B. “text/html”
C. “text/css”
D. “application/json”

10.属于HTTP进度事件的是( )
A. unload
B. start
C. stop
D. load

11.XMLHttpRequest对象中止请求和超时的方法是( )
A. stop()
B. cancel()
C. abort()
D. remove()

12.关于实现CORS支持的跨域请求,表述错误的是( )
A. 用户名和密码不会通过跨域请求发送

B. 跨域请求也不会包含其他的用户证书
C. 如果跨域请求需要这几种凭证才能成功,必须在用send()发送请求前设置XMLHttpRequest的withCredentials属性为true

D. 同源策略允许XMLHttpRequest进行跨域请求

13.关于<script>元素可以作为一种Ajax传输机制,表述错误的是( )
A. 只须设置<script>元素的src属性

B. 浏览器会发送一个HTTP请求以下载src属性所指向的URL
C. 这种机制不受同源策略的影响

D. 包含JSON编码数据的响应体会需要解码,然后执行

14.关于服务器端推送事件的Comet技术,表述错误的是( )
A. 使用new EventSource()初始化

B. Comet架构的一个常见应用是聊天应用
C. 也可以通过EventSource对象订阅聊天信息

D. 支持readyState属性、close()方法、open和error事件

二、综合题
1.用POST方法发送纯文本给服务器
function postMessage(msg) {
var request = new XMLHttpRequest(); // 新请求
request.open(“POST”, “/log.php”); // 用POST向服务器端发送脚本
// 用请求主体发送纯文本消息
request.setRequestHeader(“Content-Type”, // 请求主体将是纯文本
“text/plain;charset=UTF-8”);
request.send(msg); // 把msg作为请求主体发送
// 请求完成,我们将忽略任何响应和任何错误
}

2.获取HTTP响应的onreadystatechange
//发出一个HTTP GET请求以获得指定URL的内容
//当响应成功到达,验证它是否是纯文本
//如果是,把它传递给指定回调函数
function getText(url, callback) {
var request = new XMLHttpRequest(); // 创建新请求
request.open(“GET”, url); // 指定待获取的URL
request.onreadystatechange = function() { // 定义事件处理程序
// 如果请求完成,则它是成功的
if (request.readyState === 4 && request.status === 200) {
var type = request.getResponseHeader(“Content-Type”);
if (type.match(/^text/)) // 确保响应是文本
callback(request.responseText); // 把它传递给回调函数
}
};
request.send(null); // 立即发送请求
}

3.解析HTTP响应
//发起HTTP GET响应以获取指定URL的内容
//当响应到达时,把它以解析后的XML Document对象、解析后的JSON对象
//或字符串形式传递给回调函数
function get(url, callback) {
var request = new XMLHttpRequest(); //创建新请求
request.open(“GET”, url); //指定待获取的URL
request.onreadystatechange = function() { //定义事件监听器
//如果请求完成且成功
if (request.readyState === 4 && request.status === 200) {
//获得响应的类型
var type = request.getResponseHeader(“Content-Type”);
//检查类型,这样我们不能在将来得到HTML文档
if (type.indexOf(“xml”) !== -1 && request.responseXML)
callback(request.responseXML); // Document对象响应
else if (type === “application/json”)
callback(JSON.parse(request.responseText)); // JSON响应
else
callback(request.responseText); // String响应
}
};
request.send(null); // 字符串响应
}

4.展示了如何实现对象属性的表单编码。
Example 18-4用于HTTP请求的编码时象
/**
* 编码对象的属性,
* 如果它们是来自HTML表单的名/值对
* 使用application/x-www-form-urlencoded格式
*/
function encodeFormData(data) {
if (!data) return “”; //一直返回字符串
var pairs = []; //为了保存名=值对
for(var name in data) { //为每个名字
if (!data.hasOwnProperty(name)) continue; //跳过继承属性
if (typeof data[name] === “function”) continue; //跳过方法
var value = data[name].toString(); //把值转换成字符串
name = encodeURIComponent(name.replace(” “, “+”)); //编码名字
value = encodeURIComponent(value.replace(” “, “+”)); //编码值
pairs.push(name + “=” + value); //记住名=值对
}
return pairs.join(‘&’); //返回使用“&”连接的名/值对
}

5.使用表单编码数据发起一个HTTP Post请求
function postData(url, data, callback) {
var request = new XMLHttpRequest();
request.open(“POST”, url); //对指定URL发生POST请求
request.onreadystatechange = function() { //简单的事件处理程序
if (request.readyState === 4 && callback) //当响应完成
callback(request); //调用回调函数.
};
request.setRequestHeader(“Content-Type”, //设置Content-Type
“application/x-www-form-urlencoded”);
request.send(encodeFormData(data)); //发送表单编码的数据
}

6.使用表单编码数据发起GET请求
function getData(url, data, callback) {
var request = new XMLHttpRequest();
request.open(“GET”, url + //通过添加的编码数据获取指定的url
“?” + encodeFormData(data));
request.onreadystatechange = function() { //简单事件处理程序
if (request.readyState === 4 && callback) callback(request);
};
request.send(null); //发送请求
}

7.使用JSON编码主体来发起HTTP POST请求
function postJSON(url, data, callback) {
var request = new XMLHttpRequest();
request.open(“POST”, url); //对指定URL发送POST请求
request.onreadystatechange = function() { //简单的事件处理程序
if (request.readyState === 4 && callback) //当响应完成时
callback(request); //调用回调函数
};
request.setRequestHeader(“Content-Type”, “application/json”);
request.send(JSON.stringify(data));
}

8.使用XML文档作为其主体的HTTP POST请求
//在XML中编码什么东西、在哪儿和半径,然后向指定的URL发送POST请求
//当接收到响应时,调用回调函数
function postQuery(url, what, where, radius, callback) {
var request = new XMLHttpRequest();
request.open(“POST”, url); //对指定的URL发送POST请求
request.onreadystatechange = function() { //简单的事件处理程序
if (request.readyState === 4 && callback) callback(request);
};
// 使用<query>作为根元素创建XML文档
var doc = document.implementation.createDocument(“”, “query”, null);
var query = doc.documentElement; // <query>元素
var find = doc.createElement(“find”); //创建<find>元素
query.appendChild(find); //并把它添加到<query>中
find.setAttribute(“zipcode”, where); //设置<find>的属性
find.setAttribute(“radius”, radius);
find.appendChild(doc.createTextNode(what)); //并设置<find>的内容
//现在向服务器发送XML编码的数据
//注意将自动设置Content-Type头
request.send(doc);
}

9.使用HTTP POST请求上传文件
// 查找有data一uploadto属性的全部<input type=”file”>元素,
// 并注册onchange事件处理程序
// 这样任何选择的文件都会自动通过POST方法发送到指定的“uploadto”URL
// 服务器的响应是忽略的
whenReady(function() { //当文档准备就绪时运行
var elts = document.getElementsByTagName(“input”); //所有的input元素
for(var i = 0; i < elts.length; i++) { //遍历它们
var input = elts[i];
if (input.type !== “file”) continue; //跳过所有非文件上传元素
var url = input.getAttribute(“data-uploadto”); //获取上传URL
if (!url) continue; //跳过任何没有URL的元素
input.addEventListener(“change”, function() { //当用户选择文件时
var file = this.files[0]; //假设单个文件选择
if (!file) return; //如果没有文件,不做任何事情
var xhr = new XMLHttpRequest(); //创建新请求
xhr.open(“POST”, url); //向这个URL发送POST请求
xhr.send(file); //把文件作为主体发送
}, false);
}
});

10.使用POST方法发送multipart/form-data请求主体
function postFormData(url, data, callback) {
if (typeof FormData === “undefined”)
throw new Error(“Form Data is not implemented”);
var request = new XMLHttpRequest(); //新HTTP请求
request.open(“POST”, url); //对指定URL发送POST请求
request.onreadystatechange = function() { //简单的事件处理程序
if (request.readyState === 4 && callback) //当响应完成时
callback(request); //调用回调函数
};
var formdata = new FormData();
for(var name in data) {
if (!data.hasOwnProperty(name)) continue; //跳过继承的属性
var value = data[name];
if (typeof value === “function”) continue; //跳过方法
//每个属性变成请求的一个部分
//这里允许File对象
formdata.append(name, value); //作为一部分添加名/值对
}
// 在multipart/form-data请求主体中发送名/值对
// 每对都是请求的一个部分,注意,当传入formData对象时
// send()会自动设置Content-Type头
request.send(formdata);
}

11.监控HTTP上传进度
// 查找所有含有“fileDropTarget”类的元素
// 并注册DnD事件处理程序使它们能响应文件的拖放
// 当文件放下时,上传它们到data-uploadto属性指定的URL
whenReady(function() {
var elts = document.getElementsByClassName(“fileDropTarget”);
for(var i = 0; i < elts.length; i++) {
var target = elts[i];
var url = target.getAttribute(“data-uploadto”);
if (!url) continue;
createFileUploadDropTarget(target, url);
}
function createFileUploadDropTarget(target, url) {
//跟踪当前是否正在上传,因此我们能拒绝放下
//我们可以处理多个并发上传
//但对这个例子使用进度通知太困难了
var uploading = false;
console.log(target, url);
target.ondragenter = function(e) {
console.log(“dragenter”);
if (uploading) return; //如果正在忙,忽略拖放
var types = e.dataTransfer.types;
if (types &&
((types.contains && types.contains(“Files”)) ||
(types.indexOf && types.indexOf(“Files”) !== -1))) {
target.classList.add(“wantdrop”);
return false;
}
};
target.ondragover = function(e) { if (!uploading) return false; };
target.ondragleave = function(e) {
if (!uploading) target.classList.remove(“wantdrop”);
};
target.ondrop = function(e) {
if (uploading) return false;
var files = e.dataTransfer.files;
if (files && files.length) {
uploading = true;
var message = “Uploading files:<ul>”;
for(var i = 0; i < files.length; i++)
message += “<li>” + files[i].name + “</li>”;
message += “</ul>”;

target.innerHTML = message;
target.classList.remove(“wantdrop”);
target.classList.add(“uploading”);

var xhr = new XMLHttpRequest();
xhr.open(“POST”, url);
var body = new FormData();
for(var i = 0; i < files.length; i++) body.append(i, files[i]);
xhr.upload.onprogress = function(e) {
if (e.lengthComputable) {
target.innerHTML = message +
Math.round(e.loaded/e.total*100) +
“% Complete”;
}
};
xhr.upload.onload = function(e) {
uploading = false;
target.classList.remove(“uploading”);
target.innerHTML = “Drop files to upload”;
};
xhr.send(body);
return false;
}
target.classList.remove(“wantdrop”);
}
}
});

12.实现超时
// 发起HTTP GET请求获取指定URL的内容
// 如果响应成功到达,传入responseText给回调函数
// 如果响应在timeout毫秒内没有到达,中止这个请求
// 浏览器可能在abort()后触发“readystatechange”
// 如果是部分请求结果到达,甚至可能设置status属性
// 所以需要设置一个标记,当部分且超时的响应到达时不会调用回调函数
// 如果使用load事件就没有这个风险
function timedGetText(url, timeout, callback) {
var request = new XMLHttpRequest(); // 创建新请求
var timedout = false; // 是否超时
// 启动计时器,在timeout毫秒后将中止请求
var timer = setTimeout(function() { // 如果触发,启动一个计时器
timedout = true; // 设置标记
request.abort(); // 然后中止请求
},
timeout); // 中止请求之前的时长
request.open(“GET”, url); // 获取指定的URL
request.onreadystatechange = function() { // 定义事件处理程序
if (request.readyState !== 4) return; // 忽略未完成的请求
if (timedout) return; // 忽略中止请求
clearTimeout(timer); // 取消等待的超时
if (request.status === 200) // 如果请求成功
callback(request.responseText); // 把response传给回调函数
};
request.send(null); // 立即发送请求
}

13.使用HEAD和CORS请求链接详细信息
/**
* linkdetails.js
*
* 这个常见的JavaScript模块查询有href属性但没有title属性的所有<a>元素
* 并给它们注册onmouseover事件处理程序
* 这个事件处理程序使用XMLHttpRequest HEAD请求取得链接资源的详细信息
* 然后把这些详细信息设置为链接的title属性
* 这样它们将会在工具提示中显示
*/
whenReady(function() {
// 是否有机会使用跨域请求?
var supportsCORS = (new XMLHttpRequest()).withCredentials !== undefined;
// 遍历文档中的所有链接
var links = document.getElementsByTagName(‘a’);
for(var i = 0; i < links.length; i++) {
var link = links[i];
if (!link.href) continue; //跳过没有超链接的锚点
if (link.title) continue; //跳过已经有工具提示的链接
//如果这是一个跨域链接
if (link.host !== location.host || link.protocol !== location.protocol)
{
link.title = “Off-site link”; //假设我们不能得到任何信息
if (!supportsCORS) continue; //如果没有CORS支持就退出
//否则,我们能了解这个链接的更多信息
//所以继续前进,注册事件处理程序,于是我们可以尝试
}
//注册事件处理程序,当鼠标悬停时下载链接详细信息
if (link.addEventListener)
link.addEventListener(“mouseover”, mouseoverhandler, false);
else
link.attachEvent(“onmouseover”, mouseoverHandler);
}
function mouseoverHandler(e) {
var link = e.target || e.srcElement; // <a>元素
var url = link.href; //链接URL
var req = new XMLHttpRequest(); //新请求
req.open(“HEAD”, url); //仅仅询问头信息
req.onreadystatechange = function() { //事件处理程序
if (req.readyState !== 4) return; //忽略未完成的请求
if (req.status === 200) { //如果成功
var type = req.getResponseHeader(“Content-Type”); //获取链接的详细情况
var size = req.getResponseHeader(“Content-Length”);
var date = req.getResponseHeader(“Last-Modified”);
//在工具提示中显示详细信息
link.title = “Type: ” + type + ” \n” +
“Size: ” + size + ” \n” + “Date: ” + date;
}
else {
//如果请求失败,且链接没有“站外链接”的工具提示
//那么显示这个错误
if (!link.title)
link.title = “Couldn’t fetch details: \n” +
req.status + ” ” + req.status Text;
}
};
req.send(null);

//移除处理程序:仅想一次获取这些头信息
if (link.removeEventListener)
link.removeEventListener(“mouseover”, mouseoverhandler, false);
else
link.detachEvent(“onmouseover”, mouseoverhandler);
}
});

14.使用script元素发送JSONP请求
//根据指定的URL发送一个〕SONP请求
//然后把解析得到的响应数据传递给回调函数
//在URL中添加一个名为jsonp的查询参数,用于指定该请求的回调函数的名称
function getJSONP(url, callback) {
//为本次请求创建一个唯一的回调函数名称
var cbnum = “cb” + getJSONP.counter++; //每次自增计数器
var cbname = “getJSONP.” + cbnum; //作为JSONP函数的属性

//将回调函数名称以表单编码的形式添加到URL的查询部分中
//使用jsonp作为参数名,一些支持JSONP的服务
//可能使用其他的参数名,比如callback
if (url.indexOf(“?”) === -1) // URL没有查询部分
url += “?jsonp=” + cbname; //作为查询部分添加参数
else // 否则
url += “&jsonp=” + cbname; //作为新的参数添加它
//创建script元素用于发送请求
var script = document.createElement(“script”);
//定义将被脚本执行的回调函数
getJSONP[cbnum] = function(response) {
try {
callback(response); //处理响应数据
}
finally { //即使回调函数或响应抛出错误
delete getJSONP[cbnum]; //删除该函数
script.parentNode.removeChild(script); //移除script元素
}
};
//立即触发HTTP请求
script.src = url; //设置脚本的URL
document.body.appendChild(script); //把它添加到文档中
}
getJSONP.counter = 0; //用于创建唯一回调函数名称的计数器

15.一个使用EventSource的简易聊天客户端
<script>
window.onload = function() {
//注意一些UI细节
var nick = prompt(“Enter your nickname”); //获取用户昵称
var input = document.getElementById(“input”); //找出input表单元素
input.focus(); //设置键盘焦点
// 通过EventSource注册新消息的通知
var chat = new EventSource(“/chat”);
chat.onmessage = function(event) { //当捕获一条消息时
var msg = event.data; //从事件对象中取得文本数据
var node = document.createTextNode(msg); //把它放入一个文本节点
var div = document.createElement(“div”); //创建一个<div>
div.appendChild(node); //将文本节点插入div中
document.body.insertBefore(div, input); //将div插入input之前
input.scrollIntoView(); //保证input元素可见
}
//使用XMLHttpRequest把用户的消息发送给服务器
input.onchange = function() { //用户完成输入
var msg = nick + “: ” + input.value; //组合用户名和用户输入的信息
var xhr = new XMLHttpRequest(); //创建新的XHR
xhr.open(“POST”, “/chat”); //发送到/chat
xhr.setRequestHeader(“Content-Type”, //指明为普通的UTF-8文本
“text/plain;charset=UTF-8”);
xhr.send(msg); //发送消息
input.value = “”; //准备下次输入
}
};
</script>

16.用XMLHTTPRequest模拟EventSource
//在不支持EventSource API的浏览器里进行模拟
//需要有一个XMLHttpRequest对象在新数据写到长期存在的HTTP连接中时发送readystatechange事件
//注意,这个API的实现是不完整的
//它不支持readyState属性、close()方法、open和error事件
//消息事件也是通过onmessage属性注册的—这个版本还没有定义addEventListener()方法
if (window.EventSource === undefined) { //如果未定义EventSource对象
window.EventSource = function(url) { //像这样进行模拟
var xhr; // HTTP连接器
var evtsrc = this; //在事件处理程序中用到
var charsReceived = 0; //这样我们就可以知道什么是新的
var type = null; //检查属性响应类型
var data = “”; //存放消息数据
var eventName = “message”; //事件对象的类型字段
var lastEventId = “”; //用于和服务器再次同步
var retrydelay = 1000; //在多个连接请求之间设置延迟
var aborted = false; //设置为true表示放弃连接
//创建一个XHR对象
xhr = new XMLHttpRequest();
//定义一个事件处理程序
xhr.onreadystatechange = function() {
switch(xhr.readyState) {
case 3: processData(); break; //当数据块到达时
case 4: reconnect(); break; //当请求关闭的时候
}
};
//通过connect()创建一个长期存在的连接
connect();
//如果连接正常关闭,等待1秒钟再尝试连接
function reconnect() {
if (aborted) return; //在终止连接后不进行重连操作
if (xhr.status >= 300) return; //在报错之后不进行重连操作
setTimeout(connect, retrydelay); //等待1秒后进行重连
};
//这里的代码展示了如何建立一个连接
function connect() {
chars Received = 0;
type = null;
xhr.open(“GET”, url);
xhr.setRequestHeader(“Cache-Control”, “no-cache”);
if (lastEventId) xhr.setRequestHeader(“Last-Event-ID”, lastEventId);
xhr.send();
}
//每当数据到达的时候,会处理并触发onmessage处理程序
//这个函数处理Server-Send Events协议的细节
function processData() {
if (!type) { //如果没有准备好,先检查响应类型
type = xhr.getResponseHeader(‘Content-Type’);
if (type !== “text/event-stream”) {
aborted = true;
xhr.abort();
return;
}
}
//记录接收的数据
//获得响应中未处理的数据
var chunk = xhr.responseText.substring(charsReceived);
charsReceived = xhr.responseText.length;
//将大块的文本数据分成多行并遍历它们
var lines = chunk.replace(/(\r\n|\r|\n)$/, “”).split(/\r\n|\r|\n/);
for(var i = 0; i < lines.length; i++) {
var line = lines[i], pos = line.indexOf(“:”), name, value=””;
if (pos == 0) continue; //忽略注释
if (pos > 0) { //字段名称,值
name = line.substring(0,pos);
value = line.substring(pos+1);
if (value.charAt(0) == ” “) value = value.substring(1);
}
else name = line; //只有字段名称
switch(name) {
case “event”: eventName = value; break;
case “data”: data += value + “\n”; break;
case “id”: lastEventId = value; break;
case “retry”: retrydelay = parseInt(value) || 1000; break;
default: break; //忽略其他行
}
if (line === “”) { //一个空行意味着发送事件
if (evtsrc.onmessage && data !== “”) {
//如果末尾有新行,就裁剪新行
if (data.charAt(data.length-1) == “\n”)
data = data.substring(0, data.length-1);
evtsrc.onmessage({ //这里是一个伪造的事件对象
type: eventName, //事件类型
data: data, //事件数据
origin: url // 数据源
});
}
data = “”;
continue;
}
}
}
};
}

17.定制的Server-Sent Events聊天服务器
// 这个例子用的是服务器JavaScript,运行在NodeJS平台上
// 该聊天室的实现比较简单,而且是完全匿名的
// 将新的消息以POST发送到/chat地址,或者以GET形式从同一个URL获取消息的文本/事件流
// 创建一个GET请求到”/”来返回一个简单的HTML文件
// 这个文件包括客户端聊天UI
var http = require(‘http’); // NodeJS HTTP服务器API
//聊天客户端使用的HTML文件,在下面会用到
var clientui = require(‘fs’).readFileSync(“chatclient.html”);
var emulation = require(‘fs’).readFileSync(“Event Source Emulation.js”);
// ServerResponse对象数组,用于接收发送的事件
var clients = [];
//每20秒发送一条注释到客户端
//这样它们就不会关闭连接再重连
set Interval(function() {
clients.forEach(function(client) {
client.write(“:ping\n”);
});
}, 20000);
//创建一个新服务器
var server = new http.Server();
//当服务器获取到一个新的请求,运行回调函数
server.on(“request”, function (request, response) {
//解析请求的URL
var url = require(‘url’).parse(request.url);
//如果请求是发送到“/”,服务器就发送客户端聊天室UI
if (url.pathname === “/”) { //聊天客户端的UI请求
response.writeHead(200, {“Content-Type”: “text/html”});
response.write(“<script>” + emulation + “</script>”);
response.write(clientui);
response.end();
return;
}
//如果请求是发送到”/chat”之外的地址,则返回404
else if (url.pathname !== “/chat”) {
response.writeHead(404);
response.end();
return;
}
//如果请求类型是post,那么就有一个客户端发送了一条新的消息
if (request.method === “POST”) {
request.setEncoding(“utf8”);
var body = “”;
//在获取到数据之后,将其添加到请求主体中
request.on(“data”, function(chunk) { body += chunk; });
//当请求完成时,发送一个空响应
//并将消息传播到所有处于监听状态的客户端中
request.on(“end”, function() {
response.writeHead(200); // Respond to the request
response.end();
//将消息转换成文本/事件流格式
//确保每一行的前缀都是”data:”
//并以两个换行符结束
message = ‘data: ‘ + body.replace(‘\n’, ‘\ndata: ‘) + “\r\n\r\n”;
//发送消息给所有监听的客户端
clients.forEach(function(client) { client.write(message); });
});
}
// 否则,客户请求一个信息流
else {
//如果不是POST类型的请求,则客户端正在请求一组消息
response.writeHead(200, {‘Content-Type’: “text/event-stream” });
response.write(“data: Connected\n\n”);
//如果客户端关闭了连接
//从活动客户端数组中删除对应的响应对象
request.connection.on(“end”, function() {
clients.splice(clients.indexOf(response), 1);
response.end();
});
//记下响应对象,这样就可以向它发送未来的消息
clients.push(response);
}
});
//启动服务器,监听8000端口,访问http://localhost:8000/来进行使用它
server.listen(8000);



转载请注明:陈童的博客 » JavaScript__脚本化HTTP的练习题

喜欢 (0)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

无觅相关文章插件,快速提升流量

'; } if( dopt('d_footcode_b') ) echo dopt('d_footcode'); ?>