Par*_*dav 26 node.js amazon-mws meteor
我知道这个问题并不新鲜,但我得到的所有解决方案都是在PHP中,或者我的问题与它们不同.
我正在使用MWS Feed API提交价格和数量更新的平面文件,并始终收到以下错误:
您为Feed传递的Content-MD5 HTTP标头与我们为您的Feed计算的Content-MD5不匹配
我想在这里问3个问题: -
ContentMD5Value参数是doc中给出的可选参数,但如果我没有传递,那么它会说你必须输入ContentMD5Value.
正如ContentFeed我们给予亚马逊的doc那样.Amazon contentMD5为该文件创建,然后将该contentMD5值与contentMD5我们发送给Amazon 的值进行比较.
如果两者都匹配则OK,否则会抛出错误.但是如果假设我不发送文件,那么同样的错误也会与MD5不匹配.怎么可能?他们在为哪个文件计算MD5?因为我还没有发送文件ContentFeed.
如果我发送contentMD5标题以及参数并发送ContentFeed正文,我仍然会收到错误.
注意: - 我contentMD5使用请求模块发送标题以及表单中的参数,并使用它计算签名然后传入contentFeed正文.
我正在使用JavaScript(Meteor),我使用crpyto模块计算md5 .
首先,我认为我的md5是错的,但后来我尝试了一个在线网站,它会给我一个文件md5的md5.
对于我的文件是:
MD5值:d90e9cfde58aeba7ea7385b6d77a1f1e
Base64Encodevalue:ZDkwZTljZmRlNThhZWJhN2VhNzM4NWI2ZDc3YTFmMWU =
我从价格和数量更新下载的平面文件: -
https://sellercentral.amazon.in/gp/help/13461?ie=UTF8&Version=1&entries=0&
我在计算签名时也通过给ContentMD5Value出来计算签名.
的FeedType: '_ POST_FLAT_FILE_PRICEANDQUANTITYONLY_UPDATE_DATA_'
因为,我读了文档,我在标题中传递了MD5标题,并作为参数发送.
亚马逊医生说:
以前,亚马逊MWS接受MD5哈希作为Content-MD5标头而不是参数.将其作为参数传递可确保MD5值是方法签名的一部分,从而防止网络上的任何人篡改Feed内容.
无论是否包含ContentMD5Value参数,亚马逊MWS仍将接受Content-MD5标头.如果使用标头和参数,并且它们不匹配,您将收到InvalidParameterValue错误.
我正在使用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);
}
}))
Run Code Online (Sandbox Code Playgroud)
调用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');
Run Code Online (Sandbox Code Playgroud)
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'))
}
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
};
我也试过以下: -
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'
},
}
Run Code Online (Sandbox Code Playgroud)
我也试过没有JSON并直接在正文中发送文件读取流,即:
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'
},
}
Run Code Online (Sandbox Code Playgroud)
但每次都会出现同样的错误:
您为Feed传递的Content-MD5 HTTP标头与我们为您的Feed计算的Content-MD5不匹配
我想知道我在哪里做错了,或者提交feed API和使用请求模块发送文件的正确方法是什么.
我还尝试使用MWS上给出的代码生成MD5,但每次都发生相同的错误.
我的.txt文件如下:
sku price quantity TP-T2-00-M 2
任何帮助深表感谢
最后我得到了拉维上面所说的解决方案。实际上,我想为所有面临同样问题的人澄清几点:-
亚马逊市场API 文档没有提供正确的信息和示例。即使我猜文档还没有更新。正如在文档中他们所说,ContentMD5Value 参数值在此页面上是可选的
您可以在那里查看,他们清楚地提到该字段不是必需的,但如果您不通过,他们会给出您必须传递内容 MD5 值的错误。
所以这是错误的。ContentMD5 是必需属性。
他们在同一个文档中说,您需要发送文件数据,无论其是字段键名称中的 xml 或平面文件,即FeedContent。
但这也不是必需的,您可以发送任何名称的文件,无需提供
FeedContent文件的密钥,您只需在流中发送文件即可。
他们会给出同样的错误,即 contentMD5 与您发送的文件不匹配,因为如果他们没有找到文件,那么您发送的 contentMD5 将与该文件不匹配。因此,如果您收到ContentMD5 不匹配错误,请检查以下内容:-
检查您是否为文件生成了正确的 MD5 代码,您可以通过他们在 doc 上提供的 java 代码来检查您是否生成了正确的代码。您可以从此链接获取该信息
不要相信在线网站会生成 MD5 哈希值和 Base64 编码。
如果您的 MD5 与他们提供的 Java 代码生成的 MD5 相匹配,那么有一点很明显,您的 MD5 是正确的,因此无需对此进行更改。
一旦您的 MD5 正确,之后如果您收到相同的错误:-
Amazon MWS SubmitFeed Content-MD5 HTTP 标头与 Amazon 计算的 Content-MD5 不匹配
ContentMD5 不匹配。您只需要检查文件上传机制。因为现在您发送给亚马逊的文件要么不正确,要么您没有以正确的方式发送它。
要检查您是否发送了正确的文件,您需要检查以下内容:-
您需要发送所需的参数,如 sellerId、marketplaceId、AWSAccessKey 等作为查询参数。
如果您使用的是node.js的请求模块,您需要将form-data中的文件作为multipart发送,那么您可以看到Ravi给出的上述代码。
您只需将标题设置为:-
'内容类型':'application/x-www-form-urlencoded'
不需要以分块或制表符分隔等方式发送标头,因为我不再需要它们,它们甚至让我感到困惑,因为有人写的地方使用这个标头,而有人写的其他地方使用这个标头。 所以最后,当我准备提交这个 API 时,我不需要任何标头,而是 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.
Run Code Online (Sandbox Code Playgroud)
创建 contentMD5 的代码是:-
var fileData= fs.readFileSync('/home/parveen/Downloads/test/feed.txt','utf8');
var contentMD5Value = crypto.createHash('md5').update(fileData).digest('base64');
Run Code Online (Sandbox Code Playgroud)
因为我面临的问题是因为我通过请求模块同时使用表单和表单数据,所以我使用 qs(查询字符串)转换表单数据并将表单数据中的文件作为多部分。
这样就可以成功提交submit feed的API了。
| 归档时间: |
|
| 查看次数: |
2784 次 |
| 最近记录: |