一直以来想要做个程序,将google doc用作网盘,程序做 的差不多了才发现不是所有的人都可以上传任意类型的文件,只有商业用户才可以。商业用户是要交钱的的,这与我们倡导的免费精神相关太远。怎么办,我的心血 不能白费,google还算厚道没有把门关死,可以通过form的形式上传,我们可以模拟form的动作,就能上传了。好了费话少话,说实在的。

Google在上传时要进行身份验证。取得身份验证后,提出上传要求,这时返回一个上传地址,然后上传文件。下面一步步来。

第一步,通过网页访问DOC,其身份认证是通过cookie进行的,取得cookie的过程是

1、先访问http://docs.google.com,它通过自动跳转将你带到一个登录页面。按登录页面中的头部的set- cookie设置httpwebrequest的cookie,cookie中最重要的是HSID,然后设置url为 https://www.google.com/accounts/ServiceLoginAuth?service=writely 。然后设置提交数据ltmpl=homepage&continue=http://docs.google.com/& followup=http://docs.google.com/&service=writely&nui=1& rm=false&dsh={0}&ltmpl=homepage&ltmpl=homepage&GALX={1}& amp;Email={2}&Passwd={3}&rmShown=1&signIn=登录&asts=

其中Email填google帐户名,passwd填密码,GALX可以从cookie中找到,dsh可从页面的数据中得到。

2、再访问网址:https://www.google.com/accounts /CheckCookie?continue=http%3A%2F%2Fdocs.google.com%2F&followup=http %3A%2F%2Fdocs.google.com%2F&service=writely&ltmpl=homepage& chtml=LoginDoneHtml,取得下一步的访问地址,

3、再访问网 址:http://docs.google.com/?auth=.......,根据回应设置cookie,这时的cookie就是可以访问相当于 doc api中的token了。cookie中包含三条记录HSI,SID,writelySID。

下面是原程序:

private CookieContainer  GetAuthenticationCookie(string User,string Passwd)
        {

string GALX;
            string dsh;
            string resText = "";
            CookieContainer Auth = new CookieContainer();

//第一步
            HttpWebRequest req = CreatRequest("http://docs.google.com/");
            req.Method = "POST";
            req.ContentLength = 0;
            HttpWebResponse res = (HttpWebResponse)req.GetResponse();

//第二步
            resText = getResponseText(res);

GALX = resText.Substring(resText.IndexOf("GALX") + 26, 11);
            if ((resText.Substring(resText.IndexOf("dsh") + 32, 1)) == "-")
                dsh = resText.Substring(resText.IndexOf("dsh") + 32, 20);
            else
                dsh = resText.Substring(resText.IndexOf("dsh") + 32, 19);
            string postData = string.Format(
                "ltmpl=homepage&continue=http://docs.google.com/&followup=http: //docs.google.com/&service=writely&nui=1&rm=false&dsh= {0}&ltmpl=homepage&ltmpl=homepage&GALX={1}&Email={2}& amp; amp;Passwd={3}&rmShown=1&signIn=登录&asts="
                , dsh, GALX, User, Passwd);

req = CreatRequest("https://www.google.com/accounts/ServiceLoginAuth?service=writely ");
            req.AllowAutoRedirect = false;
            req.Method = "POST";

//设置cookie及提交数据

Auth.Add(setCookie(res, "www.google.com"));
            req.CookieContainer = Auth;
            setPostData(req, postData);
            res = (HttpWebResponse)req.GetResponse();

//第三步

req = CreatRequest(res.Headers["Location"]);
            Auth.Add(setCookie(res, "www.google.com"));
            req.CookieContainer = Auth;
            res = (HttpWebResponse)req.GetResponse();

//第四步
            resText = getResponseText(res);
            string url = resText.Substring(resText.IndexOf("url=")).Split('\"')[0];
            url = HttpUtility.HtmlDecode(url);
            url = url.Substring(5, url.Length - 6);
            req = CreatRequest(url);
            req.Method = "GET";
            req.AllowAutoRedirect = false;
            Auth.Add(setCookie(res, "www.google.com"));
            req.CookieContainer = Auth;
            res = (HttpWebResponse)req.GetResponse();
            Auth.Add(setCookie(res, "www.google.com"));

return Auth;
        }

private string getResponseText(HttpWebResponse res)
        {
            if (res.StatusCode != HttpStatusCode.OK)
                return null;
            Stream dataStream = res.GetResponseStream();
            StreamReader reader = new StreamReader(dataStream);
            string str = reader.ReadToEnd();
            reader.Close();
            return str;
        }

/// <summary>
        ///设置传送的数据
        /// </summary>
        /// <param name="req">The req.</param>
        /// <param name="postData">The post data.</param>
        private void setPostData(HttpWebRequest req, string postData)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(postData);
            req.ContentLength = bytes.Length;

using (Stream dataStream = req.GetRequestStream())
            {
                dataStream.Write(bytes, 0, bytes.Length);
                dataStream.Close();
            }

}

/// <summary>
        /// 根据response中头部的set-cookie对request中的cookie进行设置
        /// </summary>
        /// <param name="setCookie">The set cookie.</param>
        /// <param name="defaultDomain">The default domain.</param>
        /// <returns></returns>
        private CookieCollection setCookie(HttpWebResponse res, string defaultDomain)
        {
            string[] setCookie = res.Headers.GetValues("Set-Cookie");

// there is bug in it,the datetime in "set-cookie" will be sepreated in two pieces.
            List<string> a = new List<string>(setCookie);
            for (int i = setCookie.Length - 1; i > 0; i--)
            {
                if (a[i].Substring(a[i].Length - 3) == "GMT")
                {
                    a[i - 1] = a[i - 1] + ", " + a[i];
                    a.RemoveAt(i);
                    i--;
                }
            }
            setCookie = a.ToArray<string>();
            CookieCollection cookies = new CookieCollection();
            foreach (string str in setCookie)
            {
                NameValueCollection hs = new NameValueCollection();
                foreach (string i in str.Split(';'))
                {
                    int index = i.IndexOf("=");
                    if (index > 0)
                        hs.Add(i.Substring(0, index), i.Substring(index + 1));
                    else
                        switch (i)
                        {
                            case "HttpOnly":
                                hs.Add("HttpOnly", "True");
                                break;
                            case "Secure":
                                hs.Add("Secure", "True");
                                break;
                        }
                }
                Cookie ck = new Cookie();
                foreach (string Key in hs.AllKeys)
                {
                    switch (Key)
                    {
                        case "Path":
                            ck.Path = hs[Key];
                            break;
                        case "Expires":
                            ck.Expires = DateTime.Parse(hs[Key]);
                            break;
                        case "Domain":
                            ck.Domain = hs[Key];
                            break;
                        case "HttpOnly":
                            ck.HttpOnly = true;
                            break;
                        case "Secure":
                            ck.Secure = true;
                            break;
                        default:
                            ck.Name = Key;
                            ck.Value = hs[Key];
                            break;
                    }
                }
                if (ck.Domain == "") ck.Domain = defaultDomain;
                if (ck.Name != "") cookies.Add(ck);
            }
            return cookies;
        }

/// <summary>
        /// 对request进行基本的设置
        /// </summary>
        /// <param name="URL">The URL.</param>
        /// <returns></returns>
        private HttpWebRequest CreatRequest(string URL)
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(URL);
            req.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2";
            req.ServicePoint.Expect100Continue = false;
            req.ContentType = "application/x-www-form-urlencoded";

return req;
        }

整个过程很简单,但调试花了我很长时间,主要是在https下调试走了很多弯路,一 开始使用httpanalyzer,结果有bug显示的传送数据总是重复。后来还是使用fiddler才解决。但使用fiddler时在https下会出 现证书与网站 不符的错误。
解决办法是:
            ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);

public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            return true;
        }
第 一个函数在设置httpwebquest时调用就不会出现错误了。这时就可以用fiddler捕获https包了。今天就写到这里。
这里有几点猜 想未证实,授权cookie中的writelySID及SID可能与google 的client的LSID和SID相同,但HSID不知从何而来。
cookie 可以反复使用,不用每次对话都要取得cookie。
代码写得很笨拙,大家不吝赐教。
下一步,研究上传任意文件至指定目录。

转载于:https://www.cnblogs.com/zcmky/archive/2010/04/02/1703397.html

Google Doc API研究之一:模拟页面上传任意类型文件相关推荐

  1. [导入]在asp.net中利用FileUplad控件从同一个页面上传多个文件

    在页面上导入System.IO类,再使用HttpFileCollection类和Request对象捕获要传送的文件.这样就可以从一个页面上传任意多个文件. <%@ Page Language=& ...

  2. 阿里云盘如何上传压缩类型文件

    阿里云盘不限速的特点得到了很多人的点赞,但是对应一些不常见的文件不可以分享,而且分享文件有一些限制条件,比如文件夹数量,层级等,如下图所示 那么我们就会想到压缩,但是阿里云也不支持常见的压缩文件,解决 ...

  3. java 断点上传_java HTTP文件断点上传

    之前仿造uploadify写了一个HTML5版的文件上传插件,没看过的朋友可以点此先看一下~得到了不少朋友的好评,我自己也用在了项目中,不论是用户头像上传,还是各种媒体文件的上传,以及各种个性的业务需 ...

  4. 特别编辑--windows+python+django实现前端页面上传到指定路径生成个性化二维码

    等你点蓝字关注都等出蜘蛛网了 坚持梦想 就算所有人都不支持你.这条路会很曲折,你也会一度认为是不是自己选错了,但只要坚持,就算最后没有成功,但努力了就不会有遗憾. python-前端页面上传文件到指定 ...

  5. 修改form重定到iframe中,模拟异步上传文件的效果

    2019独角兽企业重金招聘Python工程师标准>>> <%@ page contentType="text/html; charset=GBK" lang ...

  6. OAF页面上传、导入、发布

    http://yedward.net/?id=215 (一)OAF页面上传 图1:将整个的开发目录上传(我这里的开发目录是oracle) 将整个开发的文件目录(myclasses下)上传到$JAVA_ ...

  7. linux环境下,模拟百度网盘上传、下载文件

    目录 1.题目 2.运行截图 3.总体设计 4.详细设计 5.源码 5.1服务端 5.2客户端 1.题目 1)模仿百度网盘实现一个文件上传.下载.浏览的终端网盘; 2)能够实现文件和目录的存储; 3) ...

  8. python模拟浏览器上传文件_Python模拟浏览器上传文件脚本的方法(Multipart/form-data格式)...

    http协议本身的原始方法不支持multipart/form-data请求,这个请求由原始方法演变而来的. multipart/form-data的基础方法是post,也就是说是由post方法来组合实 ...

  9. java 获取jsp路径_java如何获取jsp页面上传的文件路径

    展开全部 楼主:用基础的java我不知道怎么实现.但是但62616964757a686964616fe78988e69d8331333335313131第三方jar包完全可以.而且上传文件方便. 代码 ...

最新文章

  1. com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: 1 字节的 UTF-8 序列的字节 1 无效。
  2. 上线随想之2011-03-27
  3. java中Vector
  4. 02-CSS基础与进阶-day9_2018-09-12-20-29-40
  5. Qt 编码问题QTextCodec
  6. Object Relational Tool Comparison Dot Net
  7. MapJoin的原理及案例
  8. android移植jdk,重装windows后移植jdk和Android Studio
  9. 音频驱动不支持您的计算机硬件,声卡驱动装不上导致电脑没声音怎么办?
  10. 计算机网络中ipv6什么意思,路由器ipv6是什么意思(图文)
  11. 【Linux】 - Linux中查看命令文档的命令
  12. 使用endnote自动批量生成毕业论文参考文献
  13. python爬取b站视频封面_学习笔记(4)[Python爬虫]:爬取B站搜索界面的所有视频的封面...
  14. Flyme应用中心应用认领
  15. html 中div的下划线,div css布局命名时尽量避免下划线
  16. 开发人员必备的13项技能
  17. win10 tensorrtx yolov5使用方法
  18. python枚举是什么意思_什么是枚举python,
  19. UGUI动画快速制作
  20. MAP(Maximum A Posteriori,最大后验准则)算法

热门文章

  1. ARM Neon 列子 - Vector Add
  2. 自绘列表框控件显示略缩图----再稍微改进点点。。
  3. 从Linux到Meego
  4. 计算机1级 计算机基础知识,计算机一级计算机基础及MSOffice应用:计算机基础知识...
  5. 用python输入任意三条边长_如何用python求第三条边边长
  6. c++整理程序 dev_C编程从入门到实践:C语言开发工具详解(2)
  7. union all动态表_Excel VBA——动态显示图表
  8. 7-7 六度空间 (30分)_现役球员中,谁最可能成下一位30000分先生?3大前十巨星没戏...
  9. 2017计算机应用技术考研,2017年中国科学技术大学081203计算机应用技术考研专业目录与考试科目.docx...
  10. antd table 时间搜索_antd table按表格里的日期去排序操作