【问题标题】:how to use jQuery ajax calls with node.js如何在 node.js 中使用 jQuery ajax 调用
【发布时间】:2011-07-19 10:35:42
【问题描述】:

这类似于Stream data with Node.js,但我觉得这个问题没有得到充分回答。

我正在尝试使用 jQuery ajax 调用(get、load、getJSON)在页面和 node.js 服务器之间传输数据。我可以从我的浏览器点击地址并看到“Hello World!”,但是当我从我的页面尝试这个时,它失败并显示我没有得到响应。我设置了一个简单的测试页面和 hello world 示例来测试这个:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>get test</title> 
</head>
<body>
    <h1>Get Test</h1>
    <div id="test"></div>

    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js"></script>
    <script>
        $(document).ready(function() {
            //alert($('h1').length);
            $('#test').load('http://192.168.1.103:8124/');
            //$.get('http://192.168.1.103:8124/', function(data) {                
            //  alert(data);
            //});
        });
    </script>
</body>
</html>

var http = require('http');

http.createServer(function (req, res) {
    console.log('request received');
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
}).listen(8124);

【问题讨论】:

  • 我们需要知道你正在加载的文件中有什么——加载的文件中的代码是如何执行的?

标签: javascript jquery html ajax node.js


【解决方案1】:

我想您的 html 页面托管在不同的端口上。同源策略requires 在大多数浏览器中加载的文件与加载文件位于同一端口。

【讨论】:

    【解决方案2】:

    如果您的简单测试页面位于您的 hello world node.js 示例之外的其他协议/域/端口上,那么您正在执行跨域请求并违反 same origin policy 因此您的 jQuery ajax 调用(获取和加载)会静默失败.要获得这种跨域工作,您应该使用基于JSONP 的格式。例如 node.js 代码:

    var http = require('http');
    
    http.createServer(function (req, res) {
        console.log('request received');
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end('_testcb(\'{"message": "Hello world!"}\')');
    }).listen(8124);
    

    和客户端 JavaScript/jQuery:

    $(document).ready(function() {
        $.ajax({
            url: 'http://192.168.1.103:8124/',
            dataType: "jsonp",
            jsonpCallback: "_testcb",
            cache: false,
            timeout: 5000,
            success: function(data) {
                $("#test").append(data);
            },
            error: function(jqXHR, textStatus, errorThrown) {
                alert('error ' + textStatus + " " + errorThrown);
            }
        });
    });
    

    还有其他方法可以实现此功能,例如设置reverse proxy 或完全使用express 等框架构建您的Web 应用程序。

    【讨论】:

    • 太棒了,谢谢!如您的示例中所述,我将其设置为使用 jsonp,并且运行良好。
    • 很好的答案 yojimbo,这真的帮助了我。我已经发布了一些额外内容的答案。
    • 如何用express构建nodejs应用解决跨域请求问题?
    • @runrunforest:如果应用程序完全建立在 express 之上,那么您可能不需要进行跨域请求,因为所有内容都将来自同一个来源。
    • @Petsoukos 长轮询(作为基于 Web 的推送技术)在 node.js 中可以通过多个模块(例如也支持其他传输的 socket.io)进行,但是直接轮询 MySQL 将非常低效.我建议查看一些发布/订阅机制,例如可用于此目的的 redis。
    【解决方案3】:

    感谢 yojimbo 的回答。为了添加到他的示例中,我想使用 jquery 方法 $.getJSON,它在查询字符串中放置一个随机回调,所以我还想在 Node.js 中解析它。我还想传回一个对象并使用 stringify 函数。

    这是我的客户端代码。

    $.getJSON("http://localhost:8124/dummy?action=dostuff&callback=?",
    function(data){
      alert(data);
    },
    function(jqXHR, textStatus, errorThrown) {
        alert('error ' + textStatus + " " + errorThrown);
    });
    

    这是我的服务器端 Node.js

    var http = require('http');
    var querystring = require('querystring');
    var url = require('url');
    
    http.createServer(function (req, res) {
        //grab the callback from the query string   
        var pquery = querystring.parse(url.parse(req.url).query);   
        var callback = (pquery.callback ? pquery.callback : '');
    
        //we probably want to send an object back in response to the request
        var returnObject = {message: "Hello World!"};
        var returnObjectString = JSON.stringify(returnObject);
    
        //push back the response including the callback shenanigans
        res.writeHead(200, {'Content-Type': 'text/plain'});
        res.end(callback + '(\'' + returnObjectString + '\')');
    }).listen(8124);
    

    【讨论】:

    • 您的代码运行良好。请注意,使用 text/plain 作为内容类型时,您会收到 mime 错误。将 content-type 更改为 application/javascript 即可解决此问题。
    【解决方案4】:

    在服务器端使用类似下面的东西:

    http.createServer(function (request, response) {
        if (request.headers['x-requested-with'] == 'XMLHttpRequest') {
            // handle async request
            var u = url.parse(request.url, true); //not needed
    
            response.writeHead(200, {'content-type':'text/json'})
            response.end(JSON.stringify(some_array.slice(1, 10))) //send elements 1 to 10
        } else {
            // handle sync request (by server index.html)
            if (request.url == '/') {
                response.writeHead(200, {'content-type': 'text/html'})
                util.pump(fs.createReadStream('index.html'), response)
            } 
            else 
            {
                // 404 error
            }
        }
    }).listen(31337)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-10
      • 1970-01-01
      • 2013-03-06
      • 2019-08-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多