Nodejs TypeError: Cannot call method 'writeHead' of undefined

Nodejs TypeError: Cannot call method ‘writeHead’ of undefined

http://www.nodebeginner.org/index-zh-cn.html

照着这个在学习,可是进行到了不到一半的时候遇到标题中提到的问题.这个是为什么呢?


(1)index.js

var server = require("./server");
var router = require("./router");
var requestHandlers = require("./requestHandlers");
var handle = {}
handle["/"] = requestHandlers.start;
handle["/start"] = requestHandlers.start;
handle["/upload"] = requestHandlers.upload;
server.start(router.route, handle);

(2)调用server.js

var http = require("http");
var url = require("url");
function start(route, handle) {
    function onRequest(request, response) {
        var pathname = url.parse(request.url).pathname;
        console.log("Request for " + pathname + " received.");
        route(handle, pathname, response);
    }
    http.createServer(onRequest).listen(8888);
    console.log("Server has started.");
}
exports.start = start;

(3)调用router.js

function route(handle, pathname, response) {
    console.log("About to route a request for " + pathname);
    if (typeof handle[pathname] === 'function') {
        handle[pathname]();
}else{
    console.log("No request handler found for " + pathname);
    response.writeHead(404, {"Content-Type": "text/plain"});
    response.write("404 Not found");
    response.end();
}

} exports.route = route;

(4)route调用requestHandlers.js

var exec = require("child_process").exec;
function start(response) {
  console.log("Request handler 'start' was called.");
  exec("find /", { timeout: 10000, maxBuffer: 20000*1024 },
    function (error, stdout, stderr) {
      response.writeHead(200, {"Content-Type": "text/plain"});
      //response.setHeader("Content-Type", "text/html");
      response.write(stdout);
      response.end();
    });
}

function upload(response) {
  console.log("Request handler 'upload' was called.");
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello Upload");
  response.end();
}
exports.start = start;
exports.upload = upload;

6 回复

根据你提供的代码和描述的问题“Nodejs TypeError: Cannot call method ‘writeHead’ of undefined”,问题可能出现在route函数中,具体来说是在处理请求时没有正确地传递response对象。

让我们仔细检查代码:

问题分析

server.js中的onRequest函数里,response对象被传递给route函数。然而,在某些情况下,response对象可能没有被正确传递或定义。

示例代码

以下是完整的代码,确保每个部分都正确处理了response对象:

(1) index.js

var server = require("./server");
var router = require("./router");
var requestHandlers = require("./requestHandlers");

var handle = {
  "/": requestHandlers.start,
  "/start": requestHandlers.start,
  "/upload": requestHandlers.upload
};

server.start(router.route, handle);

(2) server.js

var http = require("http");
var url = require("url");

function start(route, handle) {
  function onRequest(request, response) {
    var pathname = url.parse(request.url).pathname;
    console.log("Request for " + pathname + " received.");

    // 确保传递正确的 response 对象
    route(handle, pathname, response);
  }

  http.createServer(onRequest).listen(8888);
  console.log("Server has started.");
}

exports.start = start;

(3) router.js

function route(handle, pathname, response) {
  console.log("About to route a request for " + pathname);

  if (typeof handle[pathname] === 'function') {
    // 调用请求处理器,并传递 response 对象
    handle[pathname](response);
  } else {
    console.log("No request handler found for " + pathname);
    response.writeHead(404, {"Content-Type": "text/plain"});
    response.write("404 Not found");
    response.end();
  }
}

exports.route = route;

(4) requestHandlers.js

var exec = require("child_process").exec;

function start(response) {
  console.log("Request handler 'start' was called.");
  
  exec("find /", { timeout: 10000, maxBuffer: 20000 * 1024 },
    function (error, stdout, stderr) {
      response.writeHead(200, {"Content-Type": "text/plain"});
      response.write(stdout);
      response.end();
    });
}

function upload(response) {
  console.log("Request handler 'upload' was called.");
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello Upload");
  response.end();
}

exports.start = start;
exports.upload = upload;

解释

  • server.js: onRequest 函数正确地传递了 response 对象给 route 函数。
  • router.js: route 函数确保将 response 对象传递给请求处理器(如 startupload)。
  • requestHandlers.js: 请求处理器(如 startupload)正确地使用 response 对象来设置响应头、写入内容并结束响应。

通过这种方式,你可以确保 response 对象在每个处理阶段都被正确传递和使用,从而避免 TypeError: Cannot call method 'writeHead' of undefined 错误。


start 函数谁调用的呢? 看起来像是http请求的一个handler~,但是上面代码中没有建立http服务。

信息不够,只能确定你传入 start函数的对象,不是一个 httpResponse对象

十分抱歉,各位,找到问题了. 在上面的代码中第三段

(3)调用router.js

 if (typeof handle[pathname] === 'function') {
        handle[pathname]();

上面的函数没有把response参数传递过去.

感谢fish的回答.

handlepathname; 谁因为这句话? 我也遇到了问题 还是没有解决!

根据你提供的代码,错误 TypeError: Cannot call method 'writeHead' of undefined 通常表示你在尝试调用 response.writeHead() 方法时,response 对象为 undefined。从你提供的代码来看,问题可能出在 route 函数中。

分析

server.js 中定义了 onRequest 函数,并且将该函数传递给 http.createServer() 方法。然后在 router.jsroute 函数中,如果 handle[pathname] 是一个函数,则直接调用了它。但是在这个过程中,没有将 response 对象传递给实际处理请求的函数。

解决方案

你需要确保在调用 handle[pathname] 时传递 response 参数。修改 router.js 文件中的 route 函数如下:

function route(handle, pathname, response) {
    console.log("About to route a request for " + pathname);
    if (typeof handle[pathname] === 'function') {
        handle[pathname](response);  // 将 response 传递给实际的处理函数
    } else {
        console.log("No request handler found for " + pathname);
        response.writeHead(404, {"Content-Type": "text/plain"});
        response.write("404 Not found");
        response.end();
    }
}
exports.route = route;

然后,在 index.js 中不需要任何更改。这样,当你调用 handle[pathname] 时,response 对象会被正确传递给实际的请求处理函数,从而避免 responseundefined 的情况。

示例代码

下面是修改后的 router.js 文件内容:

function route(handle, pathname, response) {
    console.log("About to route a request for " + pathname);
    if (typeof handle[pathname] === 'function') {
        handle[pathname](response);  // 传递 response 对象
    } else {
        console.log("No request handler found for " + pathname);
        response.writeHead(404, {"Content-Type": "text/plain"});
        response.write("404 Not found");
        response.end();
    }
}
exports.route = route;

通过这种方式,你可以确保 response 对象不会在处理请求的过程中丢失,从而避免 TypeError: Cannot call method 'writeHead' of undefined 错误。

回到顶部