最近项目中,用到了登陆后获取并携带cookies发起请求的业务场景,现总结写出来备忘一下。

1.定义存取cookies信息的全局变量

  1. public class HttpUtil {
  2.  
  3. /**
  4. * 用来存取cookies信息的变量.
  5. */
  6. private static CookieStore cookieStore;

2.登陆后获取cookies信息存储到全局变量

  1. public class HttpUtil {
  2.  
  3. /**
  4. *
  5. * @param httpUrl
  6. * 地址
  7. * @param paramMap
  8. * 参数
  9. *
  10. */
  11. public static String loginPost(String httpUrl, Map<String, Object> paramMap) throws Exception {
  12. if (log.isInfoEnabled()) {
  13. log.info("请求httpUrl=" + httpUrl);
  14. log.info("请求params=" + JSONObject.toJSONString(paramMap));
  15. }
  16.  
  17. // 创建httpPost
  18. HttpPost httpPost = new HttpPost(httpUrl);
  19.  
  20. // 设置参数
  21. List<NameValuePair> params = new ArrayList<>();
  22. if (paramMap != null && paramMap.size() > 0) {
  23. Set<String> keySet = paramMap.keySet();
  24. for (String key : keySet) {
  25. params.add(new BasicNameValuePair(key, UcopCommonUtil.convertString(paramMap.get(key))));
  26. }
  27. httpPost.setEntity(new UrlEncodedFormEntity(params,"UTF-8"));
  28. }
  29.  
  30. String response;
  31. DefaultHttpClient httpClient = null;
  32. try {
  33. httpClient = new DefaultHttpClient();
  34. String contentCharset = CoreProtocolPNames.HTTP_CONTENT_CHARSET;
  35. String soTimeOut = CoreConnectionPNames.SO_TIMEOUT;
  36. String connectTimeOut = CoreConnectionPNames.CONNECTION_TIMEOUT;
  37. httpClient.getParams().setParameter(contentCharset, "utf-8");
  38. httpClient.getParams().setParameter(soTimeOut, 60000);
  39. httpClient.getParams().setParameter(connectTimeOut, 60000);
  40.  
  41. HttpResponse httpResponse = httpClient.execute(httpPost);
  42.  
  43. // 获得返回结果
  44. response = EntityUtils.toString(httpResponse.getEntity(), UcopUtils.UCOP_DEFAULT_CHARSET);
  45.  
  46. // 获得cookie并存取
  47. this.cookieStore = httpClient.getCookieStore();
  48. List<Cookie> cookieList = this.cookieStore.getCookies();
  49. for (Cookie cookie : cookieList){
  50. String name =cookie.getName();
  51. String value = cookie.getValue();
  52. log.info("登陆成功,cookie name = " + name + ", cookie value = " + value);
  53. }
  54. if (log.isInfoEnabled()) {
  55. log.info("响应内容=" + response);
  56. }
  57. return response;
  58. } catch (Exception e) {
  59. log.error("HttpPost请求失败:" + e.getMessage(), e);
  60. throw new RuntimeException("HttpPost请求失败:" + e.getMessage(), e);
  61. } finally {
  62. if (null != httpClient) {
  63. httpClient.getConnectionManager().shutdown();
  64. }
  65. }
  66. }

3.携带cookie发送业务请求

  1. public class HttpUtil {
  2.  
  3. /**
  4. *
  5. * @param url 请求地址
  6. * @param paramMap 请求内容
  7. * @return 响应内容
  8. * @throws Exception
  9. */
  10. public static String requestPostWithCookie(String url, Map<String, Object> paramMap) throws Exception {
  11. if (log.isInfoEnabled()) {
  12. log.info("post请求地址:" + url);
  13. log.info("post请求内容:" + paramMap);
  14. }
  15.  
  16. long beginTime = System.currentTimeMillis();
  17. try {
  18. HttpClient httpClient = HttpClients.custom().setDefaultCookieStore(this.cookieStore).build();
  19. HttpPost httpPost = new HttpPost(url);
  20.  
  21. // 设置参数
  22. List<NameValuePair> params = new ArrayList<>();
  23. if (paramMap != null && paramMap.size() > 0) {
  24. Set<String> keySet = paramMap.keySet();
  25. for (String key : keySet) {
  26. params.add(new BasicNameValuePair(key, UcopCommonUtil.convertString(paramMap.get(key))));
  27. }
  28. httpPost.setEntity(new UrlEncodedFormEntity(params,"UTF-8"));
  29. }
  30.  
  31. // 设置请求和传输超时时间
  32. RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(120000).setConnectTimeout(120000).build();
  33. httpPost.setConfig(requestConfig);
  34.  
  35. // 发起请求
  36. HttpResponse response = httpClient.execute(httpPost);
  37.  
  38. // 获取响应数据并转换成JSON
  39. String resString = EntityUtils.toString(response.getEntity(), UcopUtils.UCOP_DEFAULT_CHARSET);
  40. log.info("post响应内容: " + resString);
  41.  
  42. return resString;
  43. } catch (Exception e) {
  44. log.error("请求失败:" + e.getMessage(), e);
  45. throw e;
  46. } finally {
  47. log.info("结束post请求,耗时(ms):" + (System.currentTimeMillis() - beginTime));
  48. }
  49. }

4.完整示例代码

  1. package com.zat.ucop.bus.service.impl;
  2.  
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.zat.ucop.service.util.UcopCommonUtil;
  5. import com.zat.ucop.service.util.UcopUtils;
  6. import org.apache.http.HttpResponse;
  7. import org.apache.http.NameValuePair;
  8. import org.apache.http.client.CookieStore;
  9. import org.apache.http.client.HttpClient;
  10. import org.apache.http.client.config.RequestConfig;
  11. import org.apache.http.client.entity.UrlEncodedFormEntity;
  12. import org.apache.http.client.methods.HttpPost;
  13. import org.apache.http.cookie.Cookie;
  14. import org.apache.http.impl.client.DefaultHttpClient;
  15. import org.apache.http.impl.client.HttpClients;
  16. import org.apache.http.message.BasicNameValuePair;
  17. import org.apache.http.params.CoreConnectionPNames;
  18. import org.apache.http.params.CoreProtocolPNames;
  19. import org.apache.http.util.EntityUtils;
  20. import org.slf4j.Logger;
  21. import org.slf4j.LoggerFactory;
  22.  
  23. import java.util.ArrayList;
  24. import java.util.List;
  25. import java.util.Map;
  26. import java.util.Set;
  27.  
  28. public class HttpUtil {
  29.  
  30. private static Logger log = LoggerFactory.getLogger(HttpUtil.class);
  31.  
  32. /**
  33. * 用来存取cookies信息的变量.
  34. */
  35. private static CookieStore cookieStore;
  36.  
  37. /**
  38. *
  39. * @param httpUrl
  40. * 地址
  41. * @param paramMap
  42. * 参数
  43. *
  44. */
  45. public static String loginPost(String httpUrl, Map<String, Object> paramMap) throws Exception {
  46. if (log.isInfoEnabled()) {
  47. log.info("请求httpUrl=" + httpUrl);
  48. log.info("请求params=" + JSONObject.toJSONString(paramMap));
  49. }
  50.  
  51. // 创建httpPost
  52. HttpPost httpPost = new HttpPost(httpUrl);
  53.  
  54. // 设置参数
  55. List<NameValuePair> params = new ArrayList<>();
  56. if (paramMap != null && paramMap.size() > 0) {
  57. Set<String> keySet = paramMap.keySet();
  58. for (String key : keySet) {
  59. params.add(new BasicNameValuePair(key, UcopCommonUtil.convertString(paramMap.get(key))));
  60. }
  61. httpPost.setEntity(new UrlEncodedFormEntity(params,"UTF-8"));
  62. }
  63.  
  64. String response;
  65. DefaultHttpClient httpClient = null;
  66. try {
  67. httpClient = new DefaultHttpClient();
  68. String contentCharset = CoreProtocolPNames.HTTP_CONTENT_CHARSET;
  69. String soTimeOut = CoreConnectionPNames.SO_TIMEOUT;
  70. String connectTimeOut = CoreConnectionPNames.CONNECTION_TIMEOUT;
  71. httpClient.getParams().setParameter(contentCharset, "utf-8");
  72. httpClient.getParams().setParameter(soTimeOut, 60000);
  73. httpClient.getParams().setParameter(connectTimeOut, 60000);
  74.  
  75. HttpResponse httpResponse = httpClient.execute(httpPost);
  76.  
  77. // 获得返回结果
  78. response = EntityUtils.toString(httpResponse.getEntity(), UcopUtils.UCOP_DEFAULT_CHARSET);
  79.  
  80. // 获得cookie并存取
  81. cookieStore = httpClient.getCookieStore();
  82. List<Cookie> cookieList = cookieStore.getCookies();
  83. for (Cookie cookie : cookieList){
  84. String name =cookie.getName();
  85. String value = cookie.getValue();
  86. log.info("登陆成功,cookie name = " + name + ", cookie value = " + value);
  87. }
  88. if (log.isInfoEnabled()) {
  89. log.info("响应内容=" + response);
  90. }
  91. return response;
  92. } catch (Exception e) {
  93. log.error("HttpPost请求失败:" + e.getMessage(), e);
  94. throw new RuntimeException("HttpPost请求失败:" + e.getMessage(), e);
  95. } finally {
  96. if (null != httpClient) {
  97. httpClient.getConnectionManager().shutdown();
  98. }
  99. }
  100. }
  101.  
  102. /**
  103. *
  104. * @param url 请求地址
  105. * @param paramMap 请求内容
  106. * @return 响应内容
  107. * @throws Exception
  108. */
  109. public static String requestPostWithCookie(String url, Map<String, Object> paramMap) throws Exception {
  110. if (log.isInfoEnabled()) {
  111. log.info("post请求地址:" + url);
  112. log.info("post请求内容:" + paramMap);
  113. }
  114.  
  115. long beginTime = System.currentTimeMillis();
  116. try {
  117. HttpClient httpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();
  118. HttpPost httpPost = new HttpPost(url);
  119.  
  120. // 设置参数
  121. List<NameValuePair> params = new ArrayList<>();
  122. if (paramMap != null && paramMap.size() > 0) {
  123. Set<String> keySet = paramMap.keySet();
  124. for (String key : keySet) {
  125. params.add(new BasicNameValuePair(key, UcopCommonUtil.convertString(paramMap.get(key))));
  126. }
  127. httpPost.setEntity(new UrlEncodedFormEntity(params,"UTF-8"));
  128. }
  129.  
  130. // 设置请求和传输超时时间
  131. RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(120000).setConnectTimeout(120000).build();
  132. httpPost.setConfig(requestConfig);
  133.  
  134. // 发起请求
  135. HttpResponse response = httpClient.execute(httpPost);
  136.  
  137. // 获取响应数据并转换成JSON
  138. String resString = EntityUtils.toString(response.getEntity(), UcopUtils.UCOP_DEFAULT_CHARSET);
  139. log.info("post响应内容: " + resString);
  140.  
  141. return resString;
  142. } catch (Exception e) {
  143. log.error("请求失败:" + e.getMessage(), e);
  144. throw e;
  145. } finally {
  146. log.info("结束post请求,耗时(ms):" + (System.currentTimeMillis() - beginTime));
  147. }
  148. }
  149.  
  150. }

补充:HttpClient获取Cookie的两种方式

1.使用DefaultHttpClient类实例化httpClient对象:

  1. package com.zat.ucop.bus.service.impl;
  2.  
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.zat.ucop.service.util.UcopCommonUtil;
  5. import com.zat.ucop.service.util.UcopUtils;
  6. import org.apache.http.HttpResponse;
  7. import org.apache.http.NameValuePair;
  8. import org.apache.http.client.CookieStore;
  9. import org.apache.http.client.HttpClient;
  10. import org.apache.http.client.config.RequestConfig;
  11. import org.apache.http.client.entity.UrlEncodedFormEntity;
  12. import org.apache.http.client.methods.HttpPost;
  13. import org.apache.http.cookie.Cookie;
  14. import org.apache.http.impl.client.DefaultHttpClient;
  15. import org.apache.http.impl.client.HttpClients;
  16. import org.apache.http.message.BasicNameValuePair;
  17. import org.apache.http.params.CoreConnectionPNames;
  18. import org.apache.http.params.CoreProtocolPNames;
  19. import org.apache.http.util.EntityUtils;
  20. import org.slf4j.Logger;
  21. import org.slf4j.LoggerFactory;
  22.  
  23. import java.util.ArrayList;
  24. import java.util.List;
  25. import java.util.Map;
  26. import java.util.Set;
  27.  
  28. public class HttpUtil {
  29.  
  30. private static Logger log = LoggerFactory.getLogger(HttpUtil.class);
  31.  
  32. /**
  33. * 用来存取cookies信息的变量.
  34. */
  35. private static CookieStore cookieStore;
  36.  
  37. /**
  38. *
  39. * @param httpUrl
  40. * 地址
  41. * @param paramMap
  42. * 参数
  43. *
  44. */
  45. public static String loginPost(String httpUrl, Map<String, Object> paramMap) throws Exception {
  46. if (log.isInfoEnabled()) {
  47. log.info("请求httpUrl=" + httpUrl);
  48. log.info("请求params=" + JSONObject.toJSONString(paramMap));
  49. }
  50.  
  51. // 创建httpPost
  52. HttpPost httpPost = new HttpPost(httpUrl);
  53.  
  54. // 设置参数
  55. List<NameValuePair> params = new ArrayList<>();
  56. if (paramMap != null && paramMap.size() > 0) {
  57. Set<String> keySet = paramMap.keySet();
  58. for (String key : keySet) {
  59. params.add(new BasicNameValuePair(key, UcopCommonUtil.convertString(paramMap.get(key))));
  60. }
  61. httpPost.setEntity(new UrlEncodedFormEntity(params,"UTF-8"));
  62. }
  63.  
  64. String response;
  65. DefaultHttpClient httpClient = null;
  66. try {
  67. httpClient = new DefaultHttpClient();
  68. String contentCharset = CoreProtocolPNames.HTTP_CONTENT_CHARSET;
  69. String soTimeOut = CoreConnectionPNames.SO_TIMEOUT;
  70. String connectTimeOut = CoreConnectionPNames.CONNECTION_TIMEOUT;
  71. httpClient.getParams().setParameter(contentCharset, "utf-8");
  72. httpClient.getParams().setParameter(soTimeOut, 60000);
  73. httpClient.getParams().setParameter(connectTimeOut, 60000);
  74.  
  75. HttpResponse httpResponse = httpClient.execute(httpPost);
  76.  
  77. // 获得返回结果
  78. response = EntityUtils.toString(httpResponse.getEntity(), UcopUtils.UCOP_DEFAULT_CHARSET);
  79.  
  80. // 获得cookie并存取
  81. 82 cookieStore = httpClient.getCookieStore();
  82. 83 List<Cookie> cookieList = cookieStore.getCookies();
  83. 84 for (Cookie cookie : cookieList){
  84. 85 String name =cookie.getName();
  85. 86 String value = cookie.getValue();
  86. 87 log.info("登陆成功,cookie name = " + name + ", cookie value = " + value);
  87. 88 }
  88. if (log.isInfoEnabled()) {
  89. log.info("响应内容=" + response);
  90. }
  91. return response;
  92. } catch (Exception e) {
  93. log.error("HttpPost请求失败:" + e.getMessage(), e);
  94. throw new RuntimeException("HttpPost请求失败:" + e.getMessage(), e);
  95. } finally {
  96. if (null != httpClient) {
  97. httpClient.getConnectionManager().shutdown();
  98. }
  99. }
  100. }
  101.  
  102. }

2.使用CloseableHttpClient类实例化httpClient对象:

  1. package com.zat.ucop.bus.service.impl;
  2.  
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.zat.ucop.service.util.UcopCommonUtil;
  5. import com.zat.ucop.service.util.UcopUtils;
  6. import org.apache.http.HttpResponse;
  7. import org.apache.http.NameValuePair;
  8. import org.apache.http.client.CookieStore;
  9. import org.apache.http.client.HttpClient;
  10. import org.apache.http.client.config.RequestConfig;
  11. import org.apache.http.client.entity.UrlEncodedFormEntity;
  12. import org.apache.http.client.methods.HttpPost;
  13. import org.apache.http.cookie.Cookie;
  14. import org.apache.http.impl.client.DefaultHttpClient;
  15. import org.apache.http.impl.client.HttpClients;
  16. import org.apache.http.message.BasicNameValuePair;
  17. import org.apache.http.params.CoreConnectionPNames;
  18. import org.apache.http.params.CoreProtocolPNames;
  19. import org.apache.http.util.EntityUtils;
  20. import org.slf4j.Logger;
  21. import org.slf4j.LoggerFactory;
  22.  
  23. import java.util.ArrayList;
  24. import java.util.List;
  25. import java.util.Map;
  26. import java.util.Set;
  27.  
  28. public class HttpUtil {
  29.  
  30. private static Logger log = LoggerFactory.getLogger(HttpUtil.class);
  31.  
  32. /**
  33. * 用来存取cookies信息的变量.
  34. */
  35. private static CookieStore cookieStore;
  36.  
  37. /**
  38. *
  39. * @param url 请求地址
  40. * @param paramMap 请求内容
  41. * @return 响应内容
  42. * @throws Exception
  43. */
  44. public static String requestPostWithCookie(String url, Map<String, Object> paramMap) throws Exception {
  45. if (log.isInfoEnabled()) {
  46. log.info("post请求地址:" + url);
  47. log.info("post请求内容:" + paramMap);
  48. }
  49.  
  50. long beginTime = System.currentTimeMillis();
  51. try {
  52. CookieStore cookieStore = new BasicCookieStore();
  53. HttpClient httpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();
  54. HttpPost httpPost = new HttpPost(url);
  55.  
  56. // 设置参数
  57. List<NameValuePair> params = new ArrayList<>();
  58. if (paramMap != null && paramMap.size() > 0) {
  59. Set<String> keySet = paramMap.keySet();
  60. for (String key : keySet) {
  61. params.add(new BasicNameValuePair(key, UcopCommonUtil.convertString(paramMap.get(key))));
  62. }
  63. httpPost.setEntity(new UrlEncodedFormEntity(params,"UTF-8"));
  64. }
  65.  
  66. // 设置请求和传输超时时间
  67. RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(120000).setConnectTimeout(120000).build();
  68. httpPost.setConfig(requestConfig);
  69.  
  70. // 发起请求
  71. HttpResponse response = httpClient.execute(httpPost);
  72.  
  73. 74 List<Cookie> cookieList = cookieStore.getCookies();
  74. 75 for (Cookie cookie : cookieList){
  75. 76 String name =cookie.getName();
  76. 77 String value = cookie.getValue();
  77. 78 log.info("cookie name = " + name + ", cookie value = " + value);
  78. 79 }
  79.  
  80. // 获取响应数据并转换成JSON
  81. String resString = EntityUtils.toString(response.getEntity(), UcopUtils.UCOP_DEFAULT_CHARSET);
  82. log.info("post响应内容: " + resString);
  83.  
  84. return resString;
  85. } catch (Exception e) {
  86. log.error("请求失败:" + e.getMessage(), e);
  87. throw e;
  88. } finally {
  89. log.info("结束post请求,耗时(ms):" + (System.currentTimeMillis() - beginTime));
  90. }
  91. }
  92.  
  93. }

HttpClient登陆后获取并携带cookies发起请求的更多相关文章

  1. 轻松把玩HttpClient之封装HttpClient工具类(五),携带Cookie的请求

    近期更新了一下HttpClientUtil工具类代码,主要是加入了一个參数HttpContext,这个是用来干嘛的呢?事实上是用来保存和传递Cookie所须要的. 由于我们有非常多时候都须要登录.然后 ...

  2. python接口自动化测试——简单的文件上传代码实现,人人网登陆后上传图片举例

    import requests '''人人网登陆,图片上传 '''def loginData(): '''登录请求参数''' data = { 'email': '13484545195', 'ico ...

  3. python接口自动化测试七:获取登录的Cookies,并关联到下一个请求

    获取登录的cookies:loginCookies = r.cookies 把获取到的cookies传入请求:cookies=loginCookies 此方法需每一次都调用登录方法,并且每一次发送请求 ...

  4. python接口自动化测试七:获取登录的Cookies

    python接口自动化测试七:获取登录的Cookies,并关联到下一个请求   获取登录的cookies:loginCookies = r.cookies 把获取到的cookies传入请求:cooki ...

  5. Node.js:实现知乎(www.zhihu.com)模拟登陆,获取用户关注主题

    前一段时间,在瞎看看 Node.js,便研究通过 Node.js 实现知乎模拟登陆.相信,有很多网站有登陆权限设置,如若用户未登陆,将会跳转至首页提醒用户登陆,无法浏览部分页面. 如若是 b/s 架构 ...

  6. (26)基于cookie的登陆认证(写入cookie、删除cookie、登陆后所有域下的网页都可访问、登陆成功跳转至用户开始访问的页面、使用装饰器完成所有页面的登陆认证)

    获取cookie request.COOKIES['key'] request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age ...

  7. 第三百三十三节,web爬虫讲解2—Scrapy框架爬虫—Scrapy模拟浏览器登录—获取Scrapy框架Cookies

    第三百三十三节,web爬虫讲解2—Scrapy框架爬虫—Scrapy模拟浏览器登录 模拟浏览器登录 start_requests()方法,可以返回一个请求给爬虫的起始网站,这个返回的请求相当于star ...

  8. 十二 web爬虫讲解2—Scrapy框架爬虫—Scrapy模拟浏览器登录—获取Scrapy框架Cookies

    模拟浏览器登录 start_requests()方法,可以返回一个请求给爬虫的起始网站,这个返回的请求相当于start_urls,start_requests()返回的请求会替代start_urls里 ...

  9. 记一次HTTPClient模拟登录获取Cookie的开发历程

    记一次HTTPClient模拟登录获取Cookie的开发历程 环境: ​ springboot : 2.7 ​ jdk: 1.8 ​ httpClient : 4.5.13 设计方案 ​ 通过新建一个 ...

随机推荐

  1. 【转】jvm 堆内存 栈内存 大小设置

    原文地址:http://blog.csdn.net/qh_java/article/details/46608395 4种方式配置不同作用域的jvm的堆栈内存! 1.Eclise 中设置jvm内存: ...

  2. vCenter Server Heartbeat

    1.简介 vCenter Server Heartbeat为VMware vCenter Server提供关键任务高可用性,保护虚拟基础架构免受硬件.网络.配置等的影响,基于Windows的服务,可为 ...

  3. 敏捷软件开发:原则、模式与实践——第11章 DIP:依赖倒置原则

    第11章 DIP:依赖倒置原则 DIP:依赖倒置原则: a.高层模块不应该依赖于低层模块.二者都应该依赖于抽象. b.抽象不应该依赖于细节.细节应该依赖于抽象. 11.1 层次化 下图展示了一个简单的 ...

  4. CSS中的三种基本的定位机制(普通流、定位、浮动)

    一.普通流 普通流中元素框的位置由元素在XHTML中的位置决定.块级元素从上到下依次排列,框之间的垂直距离由框的垂直margin计算得到.行内元素在一行中水平布置. 普通流就是html文档中的元素如块 ...

  5. python读取pop3服务器邮件并且下载

    # -*- coding: cp936 -*- import poplib import random import os def getmail(): # 蒋辉文拥有该程序权利 你可以随意使用 em ...

  6. 2.5 《硬啃设计模式》第7章 车手选车 - 生成器(Builder Pattern)

    某赛车游戏,玩家可以选择不同的车,这些车其实是采用不同性能的配件组成的,如:车胎.发动机等. 玩家选择一部车,其实就是new了一部车. 你如何考虑“new car”的代码? 要new这个车,可能需要先 ...

  7. Python之set集合与collections系列

    1>set集合:是一个无序且不重复的元素集合:访问速度快,解决了重复的问题: s2 = set(["che","liu","haha" ...

  8. 1、Semantic-UI之开发环境搭建

    下载webstrom(其他的任何可以进行前端开发的软件都可以) Download WebStorm: The Smartest JavaScript IDE by JetBrains 安装并激活web ...

  9. Android-SDCard外部存储文件读写

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses ...

  10. EDM模板制作规范

    为了保证最大的兼容性,在制作HTML的email页面时,请严格按照规范来书写: 1.页面宽度推荐500px,最大不要超过750px: 2.制作HTML的email页面时,不使用css+div来布局,最 ...