Cannot set headers after they are sent to the client

ohh0427 发布于 2019/07/23 14:31
阅读 1K+
收藏 0

收藏!数据建模最全知识体系解读!>>>

 小白勿喷,验证服务器,接收消息,正常

但加上回复消息后报错

 

(node:2692) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:470:11)
    at ServerResponse.header (D:\新建文件夹\node_modules\express\lib\response.js:771:10)
    at ServerResponse.contentType (D:\新建文件夹\node_modules\express\lib\response.js:599:15)
    at ServerResponse.send (D:\新建文件夹\node_modules\express\lib\response.js:145:14)
    at D:\新建文件夹\04\wechat\auth.js:40:13
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:2692) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:2692) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

/*
app.js
*/
const express = require('express');
const app = express();
const auth =require('./wechat/auth');

app.use(auth());

app.listen(80,()=>console.log('服务器启动成功!'));



/*
utils/tool.js
*/
const {parseString} = require('xml2js');


module.exports = {
    getUserDataAsync (req) {

        return new Promise((resolve, reject) => {
            let xmlData = '';
            req
                .on('data', data => {
                    //当流式数据传递过来时,会触发当前事件,会将数据注入到回调函数中
                    // console.log(data.toString());
                    //读取的数据是buffer,需要将其转化成字符串
                    xmlData += data.toString();
                })
                .on('end', () => {
                    resolve(xmlData);
                })
        })
    },
    parseXMLAsync (xmlData) {
        return new Promise((resolve, reject) => {
            parseString(xmlData, {trim: true}, (err, data) => {
                if (!err) {
                    resolve(data);
                } else {
                    reject('parseXMLAsync方法出了问题:' + err);
                }
            })
        })
    },
    formatMessage(jsData){
        let message = {};
        jsData = jsData.xml;
        if(typeof  jsData==='object'){
            for(let key in jsData){
                let value = jsData[key];

                    message[key]=value[0];

            }
        }
        /*ToUserName: 'gh_2e4239320189',
            FromUserName: 'oUmJ258kVOJpysoKMhDd6aOvTw28',
            CreateTime: '1563791833',
            MsgType: 'text',
            Content: '。',
            MsgId: '22388115850789053'*/
        return message;
    }
}


/*
wechat/accesstoken.js
*/
const {appID,appsecret} = require('../config');
const rp =require('request-promise-native');
const {writeFile,readFile}=require('fs');

class Wechat {
    constructor(){

    }
    getAccessToken(){
        const url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=xxxxxx&secret=xxxxxxxxxxxx'
        return new Promise((resolve, reject) => {
            rp({method: 'GET', url, json: true})
                .then(res => {
                    console.log(res);

                    res.expires_in = Date.now() + (res.expires_in - 300) * 1000;
                    resolve(res);

                })
                .catch(err => {
                    console.log(err);
                    reject('getAcessToken错误'+err);
                })
        })
    }
    saveToken(accessToken){
        accessToken=JSON.stringify(accessToken);

        return new Promise((resolve,reject)=>{
            writeFile('./accessToken.txt',accessToken,err=>{
                if(!err){
                    console.log('文件保存成功');
                    resolve();
                }else {
                    reject('save出错'+err);
                }
            })
        })

    }
    readToken(accessToken){
        return new Promise((resolve,reject)=>{
            writeFile('./accessToken.txt',(err,data)=>{
                if(!err){
                    console.log('文件读取成功');
                    data=json.parse(data);
                    resolve();
                }else {
                    reject('read出错'+err);
                }
            })
        })

    }
    isValidAccessToken(accessToken){
        if(!data&&!data.access_token&&data.expirs_in){
            return false;
        }

        if(data.expirs_in<data.now()){
         return false;
        }else {
            return true;
        }

    }
    fetchAccessToken(){
        if(this.access_token&&expires_in&&this.isValidAccessToken(this)){
            return Promise.resolve({
                access_token:this.access_token,
                expires_in:this.expirse_in
            })
        }
        return this.readToken()
                .then(async res=>{
                    if(this.isValidAccessToken(res)){
                        return Promise.resolve(res);
                        //resolve(res);
                    }else {
                        const res = await this.getAccessToken()
                        await this.saveToken(res)
                        return Promise.resolve(res);
                        //resolve(res);
                            }
                })
                .catch(async err=>{
                    const res = await this.getAccessToken()
                    await this.saveToken(res)
                    return Promise.resolve(res);
                    //resolve(res);
                })
                .then(res =>{
                    this.access_token = res.access_token;
                    this.expirse_in = res.expires_in;
                    return Promise.resolve(res);
                })
    }
}

/*
config/index.js
*/
module.exports={
    token:'xxx',
    appID:'xxxxxxxxx',
    appsecret:'xxxxxxxxxxxxxxxxxxxxxxx'
}

/*
auth.js
*/
/*验证服务期有效性*/
const  sha1 = require('sha1');
const config=require('../config');
const {getUserDataAsync,parseXMLAsync,formatMessage}=require('../utils/tool');
module.exports=()=>{
    return async (req,res,next)=>{
        const {signature,echostr,timestamp,nonce}= req.query;
        const {token} = config;
        const  sha1Str = sha1([timestamp,nonce,token].sort().join(''));

        if(req.method==='GET'){
            if(sha1Str==signature){
                res.send(echostr);
            }else {
                res.end('error');
            }}else if(req.method==='POST'){
            if(sha1Str==signature){
                res.end('error');
            }
            const xmlData = await getUserDataAsync(req);
            const jsData = await parseXMLAsync(xmlData);
            const message = await formatMessage(jsData);
            console.log(message);

            let Content='不是文本消息';

            if(message.MsgType==='text'){
                if(message.Content==='1'){
                    content='你发给我的1';
                }else if(message.Content.match('1')){
                    content='你发给我的有1';
                }else{
                    content='你发的什么东西';
                }
            }
            res.send('<xml> <ToUserName><![CDATA[o3Hfvv6kzG0WlE612_7Ua5q2_nrw]]></ToUserName><FromUserName><![CDATA[gh_2dcb2e6ba3ac]]></FromUserName><CreateTime>'+Date.now()+'</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA['+'content'+']]></Content> </xml>');

            }else {
            res.end('error');
        }
        }
    }

 

加载中
返回顶部
顶部