我知道这个问题不是新问题,但是我为此获得的所有解决方案都在PHP中,或者我的问题与此不同。

我正在使用MWS feed API提交用于价格和数量更新的平面文件,并且始终会出现以下错误:



我想在这里问3个问题:-

  • ContentMD5Value参数是doc中提供的可选参数,但是如果我未通过该参数,它将表示您必须输入ContentMD5Value。
  • 和doc中的一样,我们将ContentFeed提供给Amazon。 Amazon为该文件创建contentMD5,然后将该contentMD5值与我们发送给Amazon的contentMD5值进行比较。
    如果两者都匹配,则确定,否则将引发错误。但是,如果我不发送文件,那么同样的错误也会导致MD5不匹配。那怎么可能?他们要为哪个文件计算MD5?因为我还没有发送文件ContentFeed
  • 如果我在 header 和参数中发送contentMD5并在正文中发送ContentFeed,我仍然会收到错误。

  • 注意:-我使用请求模块在头文件中以及表单中的参数中发送contentMD5,并使用该参数计算签名,然后将contentFeed传递到正文中。

    我正在使用JavaScript( meteor ),我使用crpyto模块来计算md5。
    首先,我认为我的md5错误,但是随后我尝试了一个在线网站,该网站将给我md5作为文件md5。

    对于我的文件是:



    我从“价格和数量更新”中下载的平面文件:-



    我还通过在计算签名时提供ContentMD5Value来计算签名。



    如此,我阅读了有关在 header 中传递MD5- header 并还作为参数发送的文档。

    亚马逊文件说:



    我正在将request模块用于http请求。

    我以请求模块的形式传递了所有必需的键,卖方ID等,并在正文中传递了FeedContent

    我尝试按以下方式发送文件:

    submitFeed的方法是:-
    submitFeed : function(){
        console.log("submitFeedAPI running..");
        app  = mwsReport({auth: {sellerId:'A4TUFSCXD64V3', accessKeyId:'AKIAJBU3FTBCJUIZWF', secretKey:'Eug7ZbaLljtrnGKGFT/DTH23HJ' }, marketplace: 'IN'});
        app.submitFeedsAPI({FeedType:'_POST_FLAT_FILE_PRICEANDQUANTITYONLY_UPDATE_DATA_'},Meteor.bindEnvironment(function(err,response){
            if(err){
                console.log("error in submit feed...")
                console.log(err)
            }
            else{
                console.log("suuccess submit feed....")
                console.log(response);
            }
        }))
    

    调用Amazon SubmitFeedAPI的方法是:-
        var submitFeedsAPI =  function(options, callback){
            console.log("submitFeedsAPI running...");
        var fileReadStream = fs.createReadStream('/home/parveen/Downloads/test/testting.txt');
            var contentMD5Value = crypto.createHash('md5').update(file).digest('base64');
    
        var reqForm = {query: {"Action": "SubmitFeed", "MarketplaceId": mpList[mpCur].id, "FeedType":options.FeedType,"PurgeAndReplace":false,"ContentMD5Value":contentMD5Value}};
                mwsReqProcessor(reqForm, 'submitFeedsAPI', "submitFeedsAPIResponse", "submitFeedsAPIResult", "mwsprod-0000",false,file, callback);
        }
    
    
    also try
    
        var fileReadStream = fs.createReadStream('/home/parveen/Downloads/test/testting.txt');
        var base64Contents = fileReadStream.toString('base64');
        var contentMD5Value = crypto.createHash('md5').update(base64Contents).digest('base64');
    

    mwsReqProcessor函数如下:-
     mwsReqProcessor = function mwsReqProcessor(reqForm, name, responseKey, resultKey, errorCode,reportFlag,file, callback) {
    
            reqOpt = {
                url: mwsReqUrl,
                method: 'POST',
                timeout: 40000,
                body:{FeedContent: fs.readFileSync('/home/parveen/feedContentFile/Flat.File.PriceInventory.in.txt')},
                json:true,
                form: null,
                headers: {
                    // 'Transfer-Encoding': 'chunked',
                    //'Content-Type': 'text/xml',
                   // 'Content-MD5':'ZDkwZTljZmRlNThhZWJhN2VhNzM4NWI2ZDc3YTFmMWU=',
                    // 'Content-Type': 'text/xml; charset=iso-8859-1'
                    'Content-Type':'text/tab-separated-values;charset=UTF-8'
                },
            }
            reqOpt.form = mwsReqQryGen(reqForm);
            var r = request(reqOpt, function (err, res, body){
                console.log(err)
                console.log(res)
            })
            // var form  = r.form();
            //form.append('FeedContent',fs.createReadStream('/home/parveen/feedContent//File/Flat.File.PriceInventory.in.txt'))
        }
    

    用于mwsReqQryGen生成的方法:-
    mwsReqQryGen = function mwsReqQryGen(options) {
        var method     = (options && options.method) ? ('' + options.method) : 'POST',
            host       = (options && options.host)   ? ('' + options.host)   : mwsReqHost,
            path       = (options && options.path)   ? ('' + options.path)   : mwsReqPath,
            query      = (options && options.query)  ? options.query         : null,
    
    
            returnData = {
              "AWSAccessKeyId": authInfo.accessKeyId,
              "SellerId": authInfo.sellerId,
              "SignatureMethod": "HmacSHA256",
              "SignatureVersion": "2",
              "Timestamp": new Date().toISOString(),
               "Version":"2009-01-01",
            },
            key;
    
        if(query && typeof query === "object")
          for(key in query)
            if(query.hasOwnProperty(key)) returnData[key] = ('' + query[key]);
    
        if(authInfo.secretKey && method && host && path) {
    
          // Sort query parameters
          var keys = [],
              qry  = {};
    
          for(key in returnData)
            if(returnData.hasOwnProperty(key)) keys.push(key);
    
          keys = keys.sort();
          for(key in keys)
            if(keys.hasOwnProperty(key)) qry[keys[key]] = returnData[keys[key]];
          var sign = [method, host, path, qs.stringify(qry)].join("\n");
          console.log("..................................................")
          returnData.Signature = mwsReqSignGen(sign);
    
        }
    //console.log(returnData); // for debug
    
    return returnData;
    

    };

    我也尝试以下:
    reqOpt = {
        url: mwsReqUrl,
        method: 'POST',
        timeout: 40000,
        json:true,
        form: null,
        body:  {FeedContent: fs.createReadStream('/home/parveen/feedContentFile/Flat.File.PriceInventory.in.txt')},
        headers: {
            // 'Transfer-Encoding': 'chunked',
            //'Content-Type': 'text/xml',
           // 'Content-MD5':'ZDkwZTljZmRlNThhZWJhN2VhNzM4NWI2ZDc3YTFmMWU=',
            //   'Content-Type': 'text/xml; charset=iso-8859-1'
        },
    }
    

    我也尝试了不使用JSON的情况,并直接将文件读取流发送到
    body ,即:
    reqOpt = {
        url: mwsReqUrl,
        method: 'POST',
        timeout: 40000,
        form: null,
        body:  fs.createReadStream('/home/parveen/feedContentFile/Flat.File.PriceInventory.in.txt'),
        headers: {
            // 'Transfer-Encoding': 'chunked',
            //'Content-Type': 'text/xml',
         //   'Content-MD5':'ZDkwZTljZmRlNThhZWJhN2VhNzM4NWI2ZDc3YTFmMWU=',
            //   'Content-Type': 'text/xml; charset=iso-8859-1'
        },
    }
    

    但是每次都会出现相同的错误:



    我想知道我做错了什么,或者使用请求模块提交Feed API和发送文件的正确方法是什么。

    我也尝试使用MWS上给出的代码来生成MD5,但相同
    每次都发生错误。

    我的.txt文件如下:

    sku价格数量
    TP-T2-00-M 2

    任何帮助深表感谢

    最佳答案

    最终,我得到了如拉维所说的解决方案。 实际上,我想为所有面临相同问题的所有人清除一些要点:-

  • 亚马逊市场 API文档未提供适当的信息和示例。甚至我猜文档也没有更新。就像在doc中一样,他们说ContentMD5Value参数值是可选的on this page

    您可以在此处检查他们是否明确指出该字段不是必填字段,但是如果您未通过该字段,则他们将给出必须传递内容MD5值的错误。

  • 他们在同一文档中说,您需要通过字段键名称(即FeedContent )中的xml或平面文件发送文件数据。

  • 它们将给出相同的错误,即contentMD5与您发送的文件不匹配,这是因为如果找不到文件,则与您发送的contentMD5不匹配。因此,如果您遇到 ContentMD5不匹配错误,请检查以下内容:-
  • 检查您是否正在为文件生成正确的MD5代码,可以通过在doc上给出的Java代码来检查是否正在生成正确的代码。您可以从this link
  • 中获得
  • 不要信任在线网站来生成MD5哈希和base64编码。
  • 如果您的MD5与从Java代码生成的MD5相匹配,他们给出的结果显然就是您的MD5是正确的,因此无需对此进行更改。
  • 一旦您的MD5是正确的,此后也将得到相同的错误,即:-


  • ContentMD5不匹配。您只需要检查文件上传机制即可。
    因为现在您发送到Amazon的文件不正确,或者您发送的方式不正确。

    检查文件上传

    要检查您是否正在发送正确的文件,需要使用以下命令进行检查:-
  • 您需要发送必需的参数(例如SellerId,marketplaceId,AWSAccessKey等)作为查询参数。
  • 如果您使用的是node.js的请求模块,则需要以多部分形式将文件以form-data的形式发送,而不是上面的Ravi给出的代码。
  • 您只需要将 header 设置为:-


  • 无需将 header 发送为大块或制表符分隔等,因为我不再需要它们,它们甚至使我感到困惑,因为在某人写的地方使用此 header ,在其他地方写的人使用此 header 。
    因此,最终,由于我愿意提交此API,所以我不需要任何 header ,而无需使用application/x-www-form-urlencoded。

    例子:-
    reqOpt = {
       url: mwsReqUrl,
       method: 'POST',
       formData: {
          my_file: fs.createReadStream('file.txt')
      },
      headers: {
         'Content-Type': 'application/x-www-form-urlencoded'
      },
    qs: { }// all the parameters that you are using while creating signature.
    

    用于创建contentMD5的代码为:-
    var  fileData= fs.readFileSync('/home/parveen/Downloads/test/feed.txt','utf8');
    
    var contentMD5Value = crypto.createHash('md5').update(fileData).digest('base64');
    

    因为我面临的问题是因为我通过请求模块同时使用表单和表单数据,所以我将qs(query string)转换为表单数据,并将表单数据中的文件转换为多部分。

    因此,您可以通过这种方式成功提交用于提交供稿的API。

    08-28 15:11