私はこの質問が新しいものではないことを知っていますが、これに対して私が得るすべての解決策はPHPにあるか、私の問題はそれらとは異なります。
MWSフィードAPIを使用して、価格と数量の更新用のフラットファイルを送信していますが、常に次のエラーが発生します。
フィード用に渡したContent-MD5HTTPヘッダーが、フィード用に計算したContent-MD5と一致しませんでした
ここで3つの質問をしたいと思います:-
ContentMD5Valueパラメーターは、ドキュメントに記載されているようにオプションですが、それを渡さなかった場合は、ContentMD5Valueを入力する必要があると表示されます。
ドキュメントのように、Amazonに渡されるContentFeed
。 Amazonは、そのファイルに対してcontentMD5
を作成し、そのcontentMD5
値をAmazonに送信するcontentMD5
値と比較します。
両方が一致する場合はOK、そうでない場合はエラーがスローされます。しかし、ファイルを送信しないとすると、MD5が一致しないという同じエラーが発生します。そんなことがあるものか?彼らはどのファイルのMD5を計算していますか? ContentFeed
でファイルを送信していないためです。
contentMD5
をヘッダーとパラメーターで送信し、ContentFeed
を本文で送信しても、エラーが発生します。
注:-リクエストモジュールを使用して、ヘッダーとパラメータでcontentMD5
をフォームに送信し、それを使用して署名を計算してから、本文にcontentFeed
を渡します。
JavaScript(Meteor)を使用していますが、crpyto
モジュールを使用してmd5を計算しています。
最初に、私のmd5が間違っていると思いますが、次に、ファイルmd5のmd5を提供するオンラインWebサイトで試しました。
私のファイルは次のとおりです。
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ヘッダーを渡し、パラメーターとしても送信しました。
アマゾンドキュメントは言う:
以前は、AmazonMWSはMD5ハッシュをパラメーターではなくContent-MD5ヘッダーとして受け入れていました。これをパラメーターとして渡すと、MD5値がメソッドシグネチャの一部になり、ネットワーク上の誰もがフィードコンテンツを改ざんするのを防ぐことができます。
Amazon MWSは、ContentMD5Valueパラメーターが含まれているかどうかに関係なく、Content-MD5ヘッダーを引き続き受け入れます。ヘッダーとパラメーターの両方が使用されていて、それらが一致しない場合、InvalidParameterValueエラーが発生します。
httpリクエストにrequest
モジュールを使用しています。
必要なすべてのキー、セラー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なしで試して、ファイル読み取りストリームを本文で直接送信しました。
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'
},
}
しかし、毎回同じエラーが発生します。
フィード用に渡したContent-MD5HTTPヘッダーが、フィード用に計算したContent-MD5と一致しませんでした
どこで間違っているのか、フィードAPIを送信してリクエストモジュールを使用してファイルを送信する正しい方法を知りたいです。
また、MWSで提供されているコードを使用してMD5を生成しようとしましたが、毎回同じエラーが発生しました。
私の.txtファイルは次のとおりです:
SKU価格数量 TP-T2-00-M 2
どんな助けでも大歓迎です
ついに私はラヴィが上で言ったように解決策を得ました。 実際、同じ問題に直面しているすべての人のために、ここでクリアしたい点がいくつかあります:-
1)AmazonマーケットプレイスAPIドキュメントは適切な情報と例を提供していません。私もドキュメントが更新されていないと思います。ドキュメントのように、ContentMD5Valueパラメータ値はオプションであると彼らは言いましたここにドキュメントのリンクがあります:-
http://docs.developer.amazonservices.com/en_US/feeds/Feeds_SubmitFeed.html
そこで確認できるのは、フィールドが必須ではないことを明確に示していることですが、合格しなかった場合は、コンテンツのMD5値を渡さなければならないというエラーが表示されます。
だからそれは間違っています。 ContentMD5は必須属性です。
2)同じドキュメントで、xmlまたはフラットファイルの天気予報でファイルデータを送信する必要があると言われましたフィールドキー名、つまりFeedContent。
ただし、これも必要ありません。ファイルをストリームで送信するために必要なファイルのFeedContentキーを指定する必要はなく、任意の名前でファイルを送信できます。
3)送信したcontentMD5よりもファイルが見つからない場合、送信したcontentMD5がそれに一致しないため、ファイルを送信した天気と一致しない、または一致しないという同じエラーが発生します。 SO ContentMD5 not matchエラーが発生した場合は、以下を確認してください:-
1)ファイルに適切なMD5コードを生成していることを確認します。適切なコードを生成しているかどうかを確認できますJavaドキュメントに記載されているコード。できますリンクからそれを取得します:-
http://docs.developer.amazonservices.com/en_US/dev_guide/DG_MD5.html
2)MD5ハッシュとbase64エンコーディングを生成するためにオンラインWebサイトを信頼しないでください。
3)MD5がJavaコードから生成されたMD5と一致する場合、MD5が正しいことは明らかなので、変更する必要はありません。
4)MD5が正しければ、その後も同じエラーが発生した場合:-
Amazon MWS SubmitFeed Content-MD5HTTPヘッダーがAmazonによって計算されたContent-MD5と一致しませんでした
ContentMD5が一致しません。チェックする必要があるのはあなただけで、ファイルのアップロードメカニズムだけです。これは、Amazonに送信しているファイルが正しくないか、正しい方法で送信していないためです。
ファイルのアップロードを確認してください:-
正しいファイルを送信しているかどうかを確認するには、次のように確認する必要があります:-
1)sellerId、marketplaceId、AWSAccessKeyなどの必要なパラメーターをクエリパラメーターとして送信する必要があります。
2)node.jsのリクエストモジュールを使用している場合は、Raviによって提供された上記のコードを見ることができるよりも、フォームデータでファイルをマルチパートとして送信する必要があります。
3)ヘッダーを次のように設定する必要があります:-
'Content-Type': '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.
contentMD5を作成するためのコードは次のとおりです:-
var fileData= fs.readFileSync('/home/parveen/Downloads/test/feed.txt','utf8');
var contentMD5Value = crypto.createHash('md5').update(fileData).digest('base64');
リクエストモジュールを介してフォームとフォームデータを同時に使用しているため、問題に直面しているため、フォームデータをqs(クエリ文字列)で変換し、フォームデータ内のファイルをマルチパートとして変換します。
したがって、このようにして、フィード送信用のAPIを正常に送信できます。
どんな質問でも大歓迎ですありがとう
返信が遅れて申し訳ありませんが、フォームデータリクエストでファイルをマルチパートで送信し、リクエストモジュールの「qs」プロパティで他のクエリ文字列を送信してみませんか。次のようにリクエストを送信できます。-
reqOpt = {
url: mwsReqUrl,
method: 'POST',
formData: {
my_file: fs.createReadStream('file.txt')
},
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
qs: {
AWSAccessKeyId: '<your AWSAccessKeyId>',
SellerId: '<your SellerId>',
SignatureMethod: '<your SignatureMethod>',
SignatureVersion: '<your SignatureVersion>',
Timestamp: '<your Timestamp>',
Version: '<your Version>',
Action: 'SubmitFeed',
MarketplaceId: '<your MarketplaceId>',
FeedType: '_POST_FLAT_FILE_PRICEANDQUANTITYONLY_UPDATE_DATA_',
PurgeAndReplace: 'false',
ContentMD5Value: '<your file.txt ContentMD5Value>',
Signature: '<your Signature>'
}
}
request(reqOpt, function(err, res){
})
Amazonでは、base64エンコーディングのファイルのmd5ハッシュが必要です。
あなたのコード:
_var fileReadStream = fs.createReadStream('/path/to/file.txt');
var file = fileReadStream.toString('base64'); //'[object Object]'
var contentMD5Value = crypto.createHash('md5').update(file).digest('base64');
_
実際、このメソッドがreadStream
から継承され、文字列_'[object Object]'
_を生成する場合、Object
のtoString()
がファイルの内容を生成すると誤って想定します。
Base64-その文字列をエンコードする常にあなたが言及した_'FEGnkJwIfbvnzlmIG534uQ=='
_を生成します。
ハッシュを適切に読み取ってエンコードする場合は、次の操作を実行できます。
_var fileContents = fs.readFileSync('/path/to/file.txt'); // produces a byte Buffer
var contentMD5Value = crypto.createHash('md5').update(fileContents).digest('base64'); // properly encoded
_
これは、次のPHPスニペット:
_$contentMD5Value = base64_encode(md5_file('/path/to/file.txt', true));
_
おそらく手遅れですが、C#の重要なポイントは次のとおりです。
1)マルチパートフォーム-データがまったく機能しませんでした。次のように終了しました(簡略化):
HttpContent content = new StringContent(xmlStr, Encoding.UTF8, "application/xml");
HttpClient client = new HttpClient();
client.PostAsync(query, content)
2)query
について:
UriBuilder builder = new UriBuilder("https://mws.amazonservices.com/");
NameValueCollection query = HttpUtility.ParseQueryString(builder.Query);
query["AwsAccessKeyId"] = your_key_str;
query["FeedType"] = "_POST_ORDER_FULFILLMENT_DATA_";
... other required params
query["ContentMD5Value"] = Md5Base64(xmlStr);
builder.Query = query.ToString();
query = builder.ToString();
3)Md5base64
について
public static string Md5Base64(string xmlStr)
{
byte[] plainTextBytes = Encoding.UTF8.GetBytes(xmlStr);
MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
byte[] hash = provider.ComputeHash(plainTextBytes);
return Convert.ToBase64String(hash);
}