使用formidable接收前端上传数据后再进行异步请求会出现跨域导致失败?
发布于 8 年前 作者 JerelLin 3708 次浏览 来自 问答

前端封装FormData对象post给后端nodejs,nodejs使用formidable解析请求,到这一步为止没有出现任何问题,nodejs能成功解析请求并打印出自己期望的数据。但是我想把解析请求后得到的数据通过superagent post给python服务器,所以用的promise分隔这两段事务,但是却失败了。浏览器提示跨域…

Error: Request has been terminated Possible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.

…Possible causes: the network is offline, Origin is not allowed by Access-Control…

我把post请求部分改为简单的setTimeout这种异步任务,也出现了同样的错误。总之就是我用formidable解析请求后拿到的数据无法再进行下一步的异步任务,一执行就会提示跨域。 单独使用formidable解析请求不进行后续的异步请求不会有问题,使用假数据单独执行后续的异步请求不使用formidable解析请求得到数据也不会有问题。但组合在一起就报错了… 这个bug困扰我三天了,实在解决不了,所以特来此求各路大神帮忙了,感激不尽。 这是我的nodejs接口的代码:

router.post("/api/publish_activity", function( req, res, next ){

    //后续的异步任务
     function async_task( result ){
         return new Promise( ( resolve, reject ) => {
             console.log(  result )
             fetch_data_post( back_end_router.publish_activity, result )
         } )
     }
     //formidable解析请求
     formidablePromise( req )
         .then( ( result ) => {
             return async_task( result )
         } )
         .then( ( async_task_result ) => {
             res.json( { error : async_task_result.body.error, message : async_task_result.body.message } )
         } )
         .catch(( error ) => console.log( error ))
 })

``

这是formidablePromise,用于解析请求并返回解析后的数据:

function formidablePromise( req ){ return new Promise(( resolve, reject ) => {

    // 图片文件将要上传到哪个文件夹下面
    var uploadfoldername = "uploadfiles";
    var uploadfolderpath = path.resolve( __dirname, "../asset/", uploadfoldername );

    // 参数设置
    var form = new formidable.IncomingForm({
        encoding : "utf-8",
                uploadDir : uploadfolderpath,
                keepExtensions : true
    })

    // 保存字段
    var fieldList = {

    }
    // 保存图片url
    var fileList = [  ];

    // 解析请求
    form.parse( req )
        .on( "error", function( err ) { return reject( err ) } )
        .on( "field", function( name, value ) {
            fieldList[ name ] = value
        } )
        .on( "file", function( name, file ) {
            var filename = ( new Date(  ) ).getTime(  );
                    switch ( file.type ){
                        case "image/jpeg" :
                                    filename = filename + ".jpg"
                                    break
                            case "image/png" :
                                    filename = filename + ".png"
                                    break
                            default :
                                    filename = filename + ".png"
                                   break
                    } 
                 var file_save_path = uploadfolderpath + "/" + filename;
                 console.log( file.path );
                    fs.rename( file.path, file_save_path, function(err) {
                        if ( err ) {
                            console.log( err )
                            }
                    } );
                    var filepath = "http://" + server + ":" + port + "/" + uploadfoldername + "/" + filename;
            fileList.push( filepath );
        } )
        .on( "end", function(  ){
            var result = { fieldList : fieldList, fileList : fileList };
            resolve( result );
        } )
})

}

fetch_data_post是使用promise封装superagent的post请求的方法:

fetch_data_post : function( url, post_data, content_type ){ var content_type = typeof( content_type ) != “undefined” ? content_type : { “Content-Type” : “application/x-www-form-urlencoded” } return new Promise(( resolve, reject ) => { request .post( url ) .set( content_type ) .send( post_data ) .end(( error, result ) => { error ? reject( error ) : resolve( result ); }) }) }

回到顶部