简体   繁体   English

使用 node.js 进行基本的 Ajax 发送/接收

[英]Basic Ajax send/receive with node.js

So I'm trying to make a very basic node.js server that with take in a request for a string, randomly select one from an array and return the selected string.所以我正在尝试制作一个非常基本的 node.js 服务器,它接收一个字符串请求,从数组中随机选择一个并返回选定的字符串。 Unfortunately I'm running into a few problems.不幸的是,我遇到了一些问题。

Here's the front end:这是前端:

function newGame()
{
   guessCnt=0;
   guess="";
   server();
   displayHash();
   displayGuessStr();
   displayGuessCnt();
}

function server()
{
   xmlhttp = new XMLHttpRequest();

   xmlhttp.open("GET","server.js", true);
   xmlhttp.send();

   string=xmlhttp.responseText;
}

This should send the request to server.js:这应该将请求发送到 server.js:

var http = require('http');

var choices=["hello world", "goodbye world"];

console.log("server initialized");

http.createServer(function(request, response)
{
    console.log("request recieved");
    var string = choices[Math.floor(Math.random()*choices.length)];
    console.log("string '" + string + "' chosen");
    response.on(string);
    console.log("string sent");
}).listen(8001);

So clearly there are several things going wrong here:很明显,这里有几个问题:

  1. I get the feeling the way I am "connecting" these two files isn't correct both in the xmlhttp.open method and in using response.on to send the string back to the front end.我感觉我“连接”这两个文件的方式在xmlhttp.open方法和使用response.on将字符串发送回前端时都不正确。

  2. I'm a little confused with how I call this page on localhost.我对如何在本地主机上调用此页面感到有些困惑。 The front end is named index.html and the sever posts to 8001. What address should I be go to on localhost in order to access the initial html page after I have initialized server.js?前端命名为 index.html,服务器发布到 8001。在我初始化 server.js 后,我应该在 localhost 上访问哪个地址才能访问初始 html 页面? Should I change it to .listen(index.html) or something like that?我应该将其更改为.listen(index.html)或类似的内容吗?

  3. are there other obvious problems with how I am implementing this (using .responsetext etc.)我如何实现这个(使用.responsetext等)还有其他明显的问题.responsetext

(sorry for the long multi-question post but the various tutorials and the node.js source all assume that the user already has an understanding of these things.) (对不起,多问题的帖子很长,但各种教程和 node.js 源代码都假设用户已经了解这些东西。)

  1. Your request should be to the server, NOT the server.js file which instantiates it.您的请求应该发送到服务器,而不是实例化它的 server.js 文件。 So, the request should look something like this: xmlhttp.open("GET","http://localhost:8001/", true);所以,请求应该是这样的: xmlhttp.open("GET","http://localhost:8001/", true); Also, you are trying to serve the front-end (index.html) AND serve AJAX requests at the same URI.此外,您正在尝试为前端 (index.html) 提供服务并在同一 URI 上提供 AJAX 请求。 To accomplish this, you are going to have to introduce logic to your server.js that will differentiate between your AJAX requests and a normal http access request.为此,您必须向 server.js 引入逻辑,以区分 AJAX 请求和普通的 http 访问请求。 To do this, you'll want to either introduce GET/POST data (ie call http://localhost:8001/?getstring=true ) or use a different path for your AJAX requests (ie call http://localhost:8001/getstring ).为此,您需要引入 GET/POST 数据(即调用http://localhost:8001/?getstring=true )或为 AJAX 请求使用不同的路径(即调用http://localhost:8001/getstring )。 On the server end then, you'll need to examine the request object to determine what to write on the response.然后在服务器端,您需要检查请求对象以确定要在响应上写入什么内容。 For the latter option, you need to use the 'url' module to parse the request.对于后一个选项,您需要使用 'url' 模块来解析请求。

  2. You are correctly calling listen() but incorrectly writing the response.您正确地调用了listen()但错误地编写了响应。 First of all, if you wish to serve index.html when navigating to http://localhost:8001/ , you need to write the contents of the file to the response using response.write() or response.end() .首先,如果您希望在导航到http://localhost:8001/时提供 index.html,您需要使用response.write()response.end()将文件的内容写入response.end() First, you need to include fs=require('fs') to get access to the filesystem.首先,您需要包含fs=require('fs')以访问文件系统。 Then, you need to actually serve the file.然后,您需要实际提供文件。

  3. XMLHttpRequest needs a callback function specified if you use it asynchronously (third parameter = true, as you have done) AND want to do something with the response.如果您异步使用 XMLHttpRequest 需要指定回调函数(第三个参数 = true,正如您所做的那样)并且想要对响应执行某些操作。 The way you have it now, string will be undefined (or perhaps null ), because that line will execute before the AJAX request is complete (ie the responseText is still empty).按照您现在的方式, string将是undefined (或者可能是null ),因为该行将在 AJAX 请求完成之前执行(即 responseText 仍然为空)。 If you use it synchronously (third parameter = false), you can write inline code as you have done.如果同步使用(第三个参数=false),就可以像以前一样编写内联代码。 This is not recommended as it locks the browser during the request.不建议这样做,因为它会在请求期间锁定浏览器。 Asynchronous operation is usually used with the onreadystatechange function, which can handle the response once it is complete.异步操作通常与 onreadystatechange 函数一起使用,一旦完成就可以处理响应。 You need to learn the basics of XMLHttpRequest.您需要学习 XMLHttpRequest 的基础知识。 Start here .这里开始。

Here is a simple implementation that incorporates all of the above:这是一个包含上述所有内容的简单实现:

server.js:服务器.js:

var http = require('http'),
      fs = require('fs'),
     url = require('url'),
 choices = ["hello world", "goodbye world"];

http.createServer(function(request, response){
    var path = url.parse(request.url).pathname;
    if(path=="/getstring"){
        console.log("request recieved");
        var string = choices[Math.floor(Math.random()*choices.length)];
        console.log("string '" + string + "' chosen");
        response.writeHead(200, {"Content-Type": "text/plain"});
        response.end(string);
        console.log("string sent");
    }else{
        fs.readFile('./index.html', function(err, file) {  
            if(err) {  
                // write an error response or nothing here  
                return;  
            }  
            response.writeHead(200, { 'Content-Type': 'text/html' });  
            response.end(file, "utf-8");  
        });
    }
}).listen(8001);
console.log("server initialized");

frontend (part of index.html):前端(index.html 的一部分):

function newGame()
{
   guessCnt=0;
   guess="";
   server();
   displayHash();
   displayGuessStr();
   displayGuessCnt();
}

function server()
{
   xmlhttp = new XMLHttpRequest();
   xmlhttp.open("GET","http://localhost:8001/getstring", true);
   xmlhttp.onreadystatechange=function(){
         if (xmlhttp.readyState==4 && xmlhttp.status==200){
           string=xmlhttp.responseText;
         }
   }
   xmlhttp.send();
}

You will need to be comfortable with AJAX.您需要熟悉 AJAX。 Use the mozilla learning center to learn about XMLHttpRequest.使用 mozilla 学习中心了解 XMLHttpRequest。 After you can use the basic XHR object, you will most likely want to use a good AJAX library instead of manually writing cross-browser AJAX requests (for example, in IE you'll need to use an ActiveXObject instead of XHR).在您可以使用基本的 XHR 对象之后,您很可能希望使用一个好的 AJAX 库,而不是手动编写跨浏览器的 AJAX 请求(例如,在 IE 中,您需要使用 ActiveXObject 而不是 XHR)。 The AJAX in jQuery is excellent, but if you don't need everything else jQuery offers, find a good AJAX library here: http://microjs.com/ . jQuery 中的 AJAX 非常出色,但如果您不需要jQuery提供的所有其他功能,请在此处找到一个好的 AJAX 库: http : //microjs.com/ You will also need to get comfy with the node.js docs, found here .您还需要熟悉 node.js 文档,可在此处找到。 Search http://google.com for some good node.js server and static file server tutorials.http://google.com 上搜索一些好的 node.js 服务器和静态文件服务器教程。 http://nodetuts.com is a good place to start. http://nodetuts.com是一个很好的起点。

UPDATE: I have changed response.sendHeader() to the new response.writeHead() in the code above !!!更新:我已将上面代码中的response.sendHeader()更改为新的response.writeHead() !!!

Express makes this kind of stuff really intuitive. Express 让这种东西变得非常直观。 The syntax looks like below :语法如下所示:

var app = require('express').createServer();
app.get("/string", function(req, res) {
    var strings = ["rad", "bla", "ska"]
    var n = Math.floor(Math.random() * strings.length)
    res.send(strings[n])
})
app.listen(8001)

https://expressjs.com https://expressjs.com

If you're using jQuery on the client side you can do something like this:如果您在客户端使用 jQuery,您可以执行以下操作:

$.get("/string", function(string) {
    alert(string)
})

I was facing following error with code (nodejs 0.10.13), provided by ampersand:我遇到了由&符号提供的代码(nodejs 0.10.13)的以下错误:

origin is not allowed by access-control-allow-origin access-control-allow-origin 不允许来源

Issue was resolved changing问题已解决更改

response.writeHead(200, {"Content-Type": "text/plain"});

to

response.writeHead(200, {
                 'Content-Type': 'text/html',
                 'Access-Control-Allow-Origin' : '*'});

Here is a fully functional example of what you are trying to accomplish.这是您尝试完成的功能的完整示例。 I created the example inside of hyperdev rather than jsFiddle so that you could see the server-side and client-side code.我在 hyperdev 而不是 jsFiddle 中创建了示例,以便您可以看到服务器端和客户端代码。

View Code: https://hyperdev.com/#!/project/destiny-authorization查看代码: https : //hyperdev.com/#!/ project/ destiny-authorization

View Working Application: https://destiny-authorization.hyperdev.space/查看工作申请: https : //destiny-authorization.hyperdev.space/

This code creates a handler for a get request that returns a random string:此代码为返回随机字符串的 get 请求创建处理程序:

app.get("/string", function(req, res) {
    var strings = ["string1", "string2", "string3"]
    var n = Math.floor(Math.random() * strings.length)
    res.send(strings[n])
});

This jQuery code then makes the ajax request and receives the random string from the server.这个 jQuery 代码然后发出 ajax 请求并从服务器接收随机字符串。

$.get("/string", function(string) {
  $('#txtString').val(string);
});

Note that this example is based on code from Jamund Ferguson's answer so if you find this useful be sure to upvote him as well.请注意,此示例基于 Jamund Ferguson 的答案中的代码,因此,如果您觉得这很有用,请务必也给他点赞。 I just thought this example would help you to see how everything fits together.我只是认为这个例子会帮助你了解一切是如何组合在一起的。

RESTful API (Route): RESTful API(路由):

rtr.route('/testing')
.get((req, res)=>{
    res.render('test')
})
.post((req, res, next)=>{
       res.render('test')
})

AJAX Code: AJAX 代码:

$(function(){
$('#anyid').on('click', function(e){
    e.preventDefault()
    $.ajax({
        url: '/testing',
        method: 'GET',
        contentType: 'application/json',
        success: function(res){
            console.log('GET Request')
        }
    })
})

$('#anyid').on('submit', function(e){
    e.preventDefault()
    $.ajax({
        url: '/testing',
        method: 'POST',
        contentType: 'application/json',
        data: JSON.stringify({
            info: "put data here to pass in JSON format."
        }),
        success: function(res){
            console.log('POST Request')
        }
    })
})
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM