记录一次使用NGINX JavaScript (njs)访问外部网络问题

641 阅读1分钟

NJS 介绍

NJS 官方文档

官方示例

官方样例

async function fetch(r) {
    let results = await Promise.all([ngx.fetch('https://nginx.org/'), ngx.fetch('https://nginx.org/en/')]);

    r.return(200, JSON.stringify(results, undefined, 4));
}

在测试上述官方样例的过程中发现,该测试无法通过。

// since 0.7.0
async function lotuscc_fetch(r) {   
    var fetch_option = {
        method: 'GET',

        headers: {
            // 'Connection': 'keep-alive',
            // 'Access-Control-Allow-Credentials': 'true',
            // 'Access-Control-Allow-Origin': '*',
        }
    };
    
    let reply = await ngx.fetch('http://nginx.org/');
    // let reply = await ngx.fetch('http://127.0.0.1:8000/summary', fetch_option);   
    let body = await reply.text();
    
    r.return(200, body);
}

于是又测试了这几个样例,发现直接访问 nginx.org/ 不通过

但是访问下面的 http://127.0.0.1:8000/summary 可以通过。

image.png

排查问题:

首先我想到可能是因为跨域问题,于是在 headers中设置了用于解决跨域问题的字段。

(104条消息) CORS解决跨域问题(Nginx跨域配置)_懒的去其的博客-CSDN博客_nginx配置跨域

测试发现还是不通过。

然后通过抓包发现,主机一直在发送DNS查询,并且一直没有收到相应的响应包

image.png

猜测主机DNS查询没有处理好,ping 了一下,发现没有通过

image.png

于是换成 www.baidu.com 进行测试

let reply = await ngx.fetch('http://www.baidu.com/', fetch_option);

发现还是不行,抓包显示 DNS 还是没有响应,但是主机可以 ping 通,浏览器也能正常访问。

image.png

image.png

换个思路,查询到 www.baidu.comIP

image.png

浏览器也能正常访问

image.png

于是测试一下直接通过 IP 访问能否通过

let reply = await ngx.fetch('http://180.101.49.12/', fetch_option);

结果发现可以通过,抓包数据也显示正常

image.png

image.png