【问题】
参考百度API的官网:
http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/file_data_apis_list
中的“上传单个文件”的解释:
上传单个文件API演示 功能 上传单个文件。 百度PCS服务目前支持最大2G的单个文件上传。 HTTP请求方式 POST URL https://pcs.baidu.com/rest/2.0/pcs/file 请求参数 参数名称 类型 是否必需 描述 method string 是 固定值,upload。 access_token string 是 开发者准入标识,HTTPS调用时必须使用。 path string 是 上传文件路径(含上传的文件名称)。 注意:
file char[] 是 上传文件的内容。 ondup string 否
注意:
返回参数 参数名称 类型 UrlEncode 描述 path string 是 该文件的绝对路径。 size uint64 否 文件字节大小。 ctime uint64 否 文件创建时间。 mtime uint64 否 文件修改时间。 md5 string 否 文件的md5签名。 fs_id uint64 否 文件在PCS的临时唯一标识ID。 示例 请求示例: POST https://pcs.baidu.com/rest/2.0/pcs/file?method=upload&path=%2fapps%2falbum%2f1.JPG&access_token=b778fb598c717c0ad7ea8c97c8f3a46f 响应示例: { "path" : "/apps/album/1.jpg", "size" : 372121, "ctime" : 1234567890, "mtime" : 1234567890, "md5" : "cb123afcc12453543ef", "fs_id" : 12345, "request_id":4043312669 } |
并且也参考了:
http://developer.baidu.com/wiki/index.php?title=docs/pcs/rest/overview
中所解释的POST的例子:
2. POST请求:
方式一: POST /rest/2.0/pcs/quota?key2=value2&key3=value3 HTTP/1.1 User-Agent: curl/7.12.1 (x86_64-redhat-linux-gnu) libcurl/7.12.1 OpenSSL/0.9.7a zlib/1.2.1.2 libidn/0.5.6 Pragma: no-cache Accept: */* Host:pcs.baidu.com Content-Length:123 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryS0JIa4uHF7yHd8xJ ------WebKitFormBoundaryS0JIa4uHF7yHd8xJ Content-Disposition: form-data; name="key1" value1 ------WebKitFormBoundaryS0JIa4uHF7yHd8xJ— 方式二: POST /rest/2.0/pcs/quota HTTP/1.1 User-Agent: curl/7.12.1 (x86_64-redhat-linux-gnu) libcurl/7.12.1 OpenSSL/0.9.7a zlib/1.2.1.2 libidn/0.5.6 Pragma: no-cache Accept: */* Host:pcs.baidu.com Content-Length:123 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryS0JIa4uHF7yHd8xJ ------WebKitFormBoundaryS0JIa4uHF7yHd8xJ Content-Disposition: form-data; name="key1" value1 ------WebKitFormBoundaryS0JIa4uHF7yHd8xJ Content-Disposition: form-data; name="key2" value2 ------WebKitFormBoundaryS0JIa4uHF7yHd8xJ Content-Disposition: form-data; name="key3" value3 ------WebKitFormBoundaryS0JIa4uHF7yHd8xJ-- |
然后用代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | string [] token = respTokenJson.Split( ',' ); string tokenStr = token[2].Split( ':' )[1].Trim( '"' ); byte [] fileBytes = null ; string filename = "fileForUpload2.txt" ; string fullFilePath = @"d:\" + filename; using (FileStream fs = new FileStream(fullFilePath, FileMode.Open)) { fileBytes = new byte [fs.Length]; fs.Read(fileBytes, 0, fileBytes.Length); } StringBuilder buffer = new StringBuilder(); char [] fileCh = new char [fileBytes.Length]; for ( int i = 0; i < fileBytes.Length; i++) fileCh[i] = ( char )fileBytes[i]; buffer.Append(fileCh); //postDict = new Dictionary<string, string>(); //postDict.Add("file", buffer.ToString()); string postDataStr = buffer.ToString(); Dictionary< string , string > queryParaDict = new Dictionary< string , string >(); queryParaDict.Add( "method" , "upload" ); queryParaDict.Add( "access_token" , tokenStr); queryParaDict.Add( "path" , "/apps/测试应用/" + filename); uploadSingleFileUrl += crifanLib.quoteParas(queryParaDict); curCookies = crifanLib.getCurCookies(); newCookies = new CookieCollection(); foreach (Cookie ck in curCookies) { if (ck.Name == "BAIDUID" || ck.Name == "BDUSS" ) { ck.Domain = "pcs.baidu.com" ; } newCookies.Add(ck); } crifanLib.setCurCookies(newCookies); string boundaryValue = "----WebKitFormBoundaryS0JIa4uHF7yHd8xJ" ; string boundaryExpression = "boundary=" + boundaryValue; headerDict = new Dictionary< string , string >(); headerDict.Add( "Pragma" , "no-cache" ); headerDict.Add( "Content-Type" , "multipart/form-data;" + " " + boundaryExpression); postDataStr = boundaryValue + "\r\n" + "Content-Disposition: form-data; name=\"file\"" + "\r\n" + postDataStr + "\r\n" + boundaryValue; //string str = crifanLib.getUrlRespHtml( // string.Format(@"https://pcs.baidu.com/rest/2.0/pcs/file?method=upload&path=%2Fapps%2F%E6%B5%8B%E8%AF%95%E5%BA%94%E7%94%A8%2F78.jpg&access_token={0}", tokenStr), // headerDict, postDict); string respJson = crifanLib.getUrlRespHtml(uploadSingleFileUrl, headerDict, null , null , postDataStr: postDataStr); |
结果出错,出现403:
【解决过程】
1。很明显,403是就是禁止访问,一般都是权限错误。
但是此处确保对应的access_token等值是正常的,即没有权限方面的错误的。
2.百度官网:
http://developer.baidu.com/wiki/index.php?title=docs/cplat/stor/faq
也说了,403的话,是:
返回403是什么意思?这种情况一般是权限验证没有通过。可能有如下几种情况:
|
3.后来别处调试的结果,貌似也是如预期的:
4.然后调试发现,此时的request header是,正常的:
{Accept: */* User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E Accept-Encoding: gzip, deflate,gzip Content-Type: multipart/form-data; boundary=—-WebKitFormBoundaryS0JIa4uHF7yHd8xJ Host: pcs.baidu.com Cookie: $Version=1; BAIDUID=6D174687C22FA05F53A9DB633FC499D8:FG=1; $Path=/; BDUSS=5JTlV4aEMyMTJnc2hxYkpud3JFTldlMC02cjdRUHJXcGEtRnpXVmJoaWVSN05SQVFBQUFBJCQAAAAAAAAAAAEAAAAZP0gCYWdhaW5pbnB1dDMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJ66i1GeuotRNH Content-Length: 180 Expect: 100-continue Connection: Keep-Alive } |
以及对应的post data是:
"—-WebKitFormBoundaryS0JIa4uHF7yHd8xJ Content-Disposition: form-data; name="file" 6222021102008788781 home abc: 6228480670539546416 —-WebKitFormBoundaryS0JIa4uHF7yHd8xJ" |
也符合其规范的。
但是结果就是不对,始终是403错误。
5.再去试试,把所有的,当然的cookie,都改为此处的domain:
1 2 3 4 5 6 7 8 9 10 11 12 | curCookies = crifanLib.getCurCookies(); newCookies = new CookieCollection(); foreach (Cookie ck in curCookies) { //if (ck.Name == "BAIDUID" || ck.Name == "BDUSS") //{ ck.Domain = "pcs.baidu.com" ; //} newCookies.Add(ck); } crifanLib.setCurCookies(newCookies); |
试试效果。
结果还是错误依旧。
6.后来又试了试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | string [] token = respTokenJson.Split( ',' ); string tokenStr = token[2].Split( ':' )[1].Trim( '"' ); byte [] fileBytes = null ; string filename = "fileForUpload2.txt" ; string fullFilePath = @"d:\" + filename; using (FileStream fs = new FileStream(fullFilePath, FileMode.Open)) { fileBytes = new byte [fs.Length]; fs.Read(fileBytes, 0, fileBytes.Length); } StringBuilder buffer = new StringBuilder(); char [] fileCh = new char [fileBytes.Length]; for ( int i = 0; i < fileBytes.Length; i++) fileCh[i] = ( char )fileBytes[i]; buffer.Append(fileCh); //postDict = new Dictionary<string, string>(); //postDict.Add("file", buffer.ToString()); string fileDataStr = buffer.ToString(); Dictionary< string , string > queryParaDict = new Dictionary< string , string >(); queryParaDict.Add( "method" , "upload" ); queryParaDict.Add( "access_token" , tokenStr); //queryParaDict.Add("path", "/apps/测试应用/" + filename); //queryParaDict.Add("path", "/apps/测试应用/"); uploadSingleFileUrl += crifanLib.quoteParas(queryParaDict); curCookies = crifanLib.getCurCookies(); newCookies = new CookieCollection(); foreach (Cookie ck in curCookies) { //if (ck.Name == "BAIDUID" || ck.Name == "BDUSS") //{ ck.Domain = "pcs.baidu.com" ; //} newCookies.Add(ck); } crifanLib.setCurCookies(newCookies); string boundaryValue = "----WebKitFormBoundaryS0JIa4uHF7yHd8xJ" ; string boundaryExpression = "boundary=" + boundaryValue; headerDict = new Dictionary< string , string >(); headerDict.Add( "Pragma" , "no-cache" ); headerDict.Add( "Content-Type" , "multipart/form-data;" + " " + boundaryExpression); string postDataStr = "" ; postDataStr += boundaryValue + "\r\n" + "Content-Disposition: form-data; name=\"Filename\"" + "\r\n" + filename + "\r\n" ; postDataStr += boundaryValue + "\r\n" + "Content-Disposition: form-data; name=\"path\"" + "\r\n" + "/apps/测试应用/" + "\r\n" ; postDataStr += boundaryValue + "\r\n" + "Content-Disposition: form-data; name=\"Filedata\"; filename=\"" + filename + "\" \r\n" + "Content-Type: application/octet-stream" + "\r\n" + fileDataStr + "\r\n" + boundaryValue; //postDataStr += boundaryValue + "\r\n" // + "Content-Disposition: form-data; name=\"file\"" + "\r\n" // + fileDataStr + "\r\n" // + boundaryValue; //string str = crifanLib.getUrlRespHtml( // string.Format(@"https://pcs.baidu.com/rest/2.0/pcs/file?method=upload&path=%2Fapps%2F%E6%B5%8B%E8%AF%95%E5%BA%94%E7%94%A8%2F78.jpg&access_token={0}", tokenStr), // headerDict, postDict); string respJson = crifanLib.getUrlRespHtml(uploadSingleFileUrl, headerDict, null , null , postDataStr: postDataStr); |
结果错误依旧。
6.后来,参考:
http://developer.baidu.com/wiki/index.php?title=docs/pcs/guide/usage_example
以为,找到了之前的错误,然后去访问自己的:
可以看到所需要的界面,可以获得百度网盘创建文件夹并修改的那个权限了。
然后可以访问到:
对应的网页显示的是“百度 OAuth2.0”的那个界面了。
然后可以获得对应的:
access_token=3.60b12647a72d958bf77e07a4d58b8d93.2592000.1370768746.1057380247-758730
然后就再去写对应的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | void emulateBaiduApi_crifanProcess() { string respHtml = "" ; Dictionary< string , string > headerDict; HttpWebResponse resp; //1. access https headerDict = new Dictionary< string , string >(); headerDict.Add( "allowautoredirect" , "false" ); headerDict.Add( "Accept" , "application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*" ); string getNetdiskTokenUrl = "https://openapi.baidu.com/oauth/2.0/authorize?response_type=token&client_id=" + txbBaiduApiKey.Text + "&redirect_uri=oob&scope=netdisk" ; resp = crifanLib.getUrlResponse(getNetdiskTokenUrl, headerDict); string redirectedAuthUrl = resp.Headers[ "Location" ]; //2.access http //respHtml = crifanLib.getUrlRespHtml(redirectedAuthUrl); //4. get token value + txbBaiduUsername.Text + "&isPhone=false&tpl=dev&immediatelySubmit=false" ; respHtml = crifanLib.getUrlRespHtml(loginItemInfoUrl); //token:'9563cab84ccd1ad32c8deccc6ea5cc19' string tokenValue = "" ; if (crifanLib.extractSingleStr( @"token:'(\w+)'" , respHtml, out tokenValue)) { headerDict = new Dictionary< string , string >(); headerDict.Add( "Referer" , getNetdiskTokenUrl); /* username=againinput3 &password=limaolin &verifycode= &mem_pass=on &charset=utf-8 &index=0 &safeflg=0 &staticpage=http%3A%2F%2Fopenapi.baidu.com%2Fstatic%2Fcommon%2Fpopup_login%2Fv2Jump.html &loginType=1 &tpl=dev &codestring= &token=587092c1d3efb35255f9bed00ade4a0d &callback=parent.bdPass.api.loginLite._submitCallBack */ Dictionary< string , string > postDict = new Dictionary< string , string >(); postDict.Add( "username" , txbBaiduUsername.Text); postDict.Add( "password" , txbBaiduPassword.Text); postDict.Add( "verifycode" , "" ); postDict.Add( "mem_pass" , "on" ); postDict.Add( "charset" , "utf-8" ); postDict.Add( "index" , "0" ); postDict.Add( "safeflg" , "0" ); postDict.Add( "staticpage" , staticpage); postDict.Add( "loginType" , "1" ); postDict.Add( "tpl" , "dev" ); postDict.Add( "codestring" , "" ); postDict.Add( "token" , tokenValue); postDict.Add( "callback" , "parent.bdPass.api.loginLite._submitCallBack" ); string loginBaiduRespHtml = crifanLib.getUrlRespHtml(baiduMainLoginUrl, headerDict, postDict); //6. access encodeURI string encodeUri = "" ; if (crifanLib.extractSingleStr( @"encodeURI\('(http.+?)'\);" , loginBaiduRespHtml, out encodeUri)) { respHtml = crifanLib.getUrlRespHtml(encodeUri); } //!!! prepare cookies //BAIDUID C912FC868D7C8BF115F01C9B67AE55DE:FG=1 //BDUSS WRaNUptRUNORjE4aU5xNlpBaTVtYk1-ZWhCR0JpNzV0Z2s2YX5vUzVoeGd-NjVSQVFBQUFBJCQAAAAAAAAAAAEAAAAZP0gCYWdhaW5pbnB1dDMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGByh1FgcodRS CookieCollection curCookies = crifanLib.getCurCookies(); CookieCollection newCookies = new CookieCollection(); foreach (Cookie ck in curCookies) { if (ck.Name == "BAIDUID" || ck.Name == "BDUSS" ) { ck.Domain = "openapi.baidu.com" ; } newCookies.Add(ck); } crifanLib.setCurCookies(newCookies); headerDict = new Dictionary< string , string >(); headerDict.Add( "allowautoredirect" , "false" ); resp = crifanLib.getUrlResponse(redirectedAuthUrl, headerDict); //http://openapi.baidu.com/oauth/2.0/login_success#expires_in=2592000&access_token=3.8826e8f1743164248f505698ccfdeb59.2592000.1370769262.1057380247-758730&session_secret=b52efa6bb90ba462e0a08a119ae7226d&session_key=94rrl19KodEPm330pCKGu%2FD3HU%2FDFI4Hp8RnS7KdHaQOrJjFBReW%2FsAtwxCS7uarcpHM2ThiBhysJDABwpy1g3q%2FVJnUiec%3D&scope=basic+netdisk string includeTokenUrl = resp.Headers[ "Location" ]; txbRespTokenJson.Text = includeTokenUrl; //http://openapi.baidu.com/oauth/2.0/login_success#expires_in=2592000&access_token=3.d316783ec1e6a9d86212dd22343914f0.2592000.1370771017.1057380247-758730&session_secret=3e46ebad3478e48db90901f01177ff3c&session_key=94q3jz3ociQ590uWfkgBkhVr5FbdUHdYMEEnI4T2rYkkUDcaBqzDm%2FveX5Vk4PJ1tSv6c4NQWq%2FbElZs%2Bxqd7Tg%2Fthh2eJI%3D&scope=basic+netdisk string netdiskAccesstoken = "" ; if (crifanLib.extractSingleStr( @"&access_token=(.+?)&" , includeTokenUrl, out netdiskAccesstoken)) { byte [] fileBytes = null ; string filename = "fileForUpload3.txt" ; string fullFilePath = @"d:\" + filename; using (FileStream fs = new FileStream(fullFilePath, FileMode.Open)) { fileBytes = new byte [fs.Length]; fs.Read(fileBytes, 0, fileBytes.Length); } StringBuilder buffer = new StringBuilder(); char [] fileCh = new char [fileBytes.Length]; for ( int i = 0; i < fileBytes.Length; i++) fileCh[i] = ( char )fileBytes[i]; buffer.Append(fileCh); //postDict = new Dictionary<string, string>(); //postDict.Add("file", buffer.ToString()); string fileDataStr = buffer.ToString(); Dictionary< string , string > queryParaDict = new Dictionary< string , string >(); queryParaDict.Add( "method" , "upload" ); queryParaDict.Add( "access_token" , netdiskAccesstoken); queryParaDict.Add( "path" , "/apps/测试应用/" + filename); uploadSingleFileUrl += crifanLib.quoteParas(queryParaDict); curCookies = crifanLib.getCurCookies(); newCookies = new CookieCollection(); foreach (Cookie ck in curCookies) { if (ck.Name == "BAIDUID" || ck.Name == "BDUSS" ) { ck.Domain = "pcs.baidu.com" ; } newCookies.Add(ck); } crifanLib.setCurCookies(newCookies); string boundaryValue = "----WebKitFormBoundaryS0JIa4uHF7yHd8xJ" ; string boundaryExpression = "boundary=" + boundaryValue; headerDict = new Dictionary< string , string >(); headerDict.Add( "Pragma" , "no-cache" ); headerDict.Add( "Content-Type" , "multipart/form-data;" + " " + boundaryExpression); string postDataStr = "" ; //postDataStr += boundaryValue + "\r\n" // + "Content-Disposition: form-data; name=\"Filename\"" + "\r\n" // + filename + "\r\n"; //postDataStr += boundaryValue + "\r\n" // + "Content-Disposition: form-data; name=\"path\"" + "\r\n" // + "/apps/测试应用/" + "\r\n"; //postDataStr += boundaryValue + "\r\n" // + "Content-Disposition: form-data; name=\"Filedata\"; filename=\"" + filename + "\" \r\n" // + "Content-Type: application/octet-stream" + "\r\n" // + fileDataStr + "\r\n" // + boundaryValue; postDataStr += boundaryValue + "\r\n" + "Content-Disposition: form-data; name=\"file\"" + "\r\n" + fileDataStr + "\r\n" + boundaryValue; string respJson = crifanLib.getUrlRespHtml(uploadSingleFileUrl, headerDict, null , null , postDataStr: postDataStr); } } } |
结果是,还是同样的403的错误,彻底无语了。
转载请注明:在路上 » 【未解决】通过百度API上传单个文件出现403的错误