下载MetaTrader 5

WebRequest

发送 HTTP 请求到指定服务器。 该函数有两个版本:

1. 发送简单请求 使用内容-类型标题的"key=value"类型application/x-www-form-urlencoded

int  WebRequest(
   const string      method,           // HTTP 请求方式
   const string      url,              // url 地址
   const string      cookie,           // cookie
   const string      referer,          // 参照页
   int               timeout,          // 超时
   const char        &data[],          // HTTP请求信息数组
   int               data_size,        // data[] 数组大小
   char              &result[],        // 服务器响应数据数组
   string            &result_headers   // 服务器响应标头
   );

2. 发送任何类型的请求 为了各种网络服务的更灵活互动指定自定义的标题设置。

int  WebRequest(
   const string      method,           // HTTP 方法
   const string      url,              // URL
   const string      headers,          // 标题 
   int               timeout,          // 超时
   const char        &data[],          // HTTP 信息主体的数组
   char              &result[],        // 包含服务器反应数据的数组
   string            &result_headers   // 服务器响应标题
   );

参数

method

[in]  HTTP 请求方法。

url

[in]  URL 地址。

headers

[in]   "key: value"类型的请求标题,以分行符 "\r\n"分隔。

cookie

[in]  Cookie。

referer

[in]  HTTP 请求标头的推荐页字段

timeout

[in]  超时时间以毫秒为单位。

data[]

[in] HTTP 请求信息数组。

data_size

[in]  data[] 数组大小。

result[]

[out]  服务器响应数据数组。

result_headers

[out]  服务器响应标头。

返回值

服务器响应的HTTP 状态码,或错误情况下的 -1 。

注意

若要能够使用WebRequest 函数,您必须在“选项”窗口“EA交易”标签的允许URLs列表中添加一个URL。

WebRequest 是一个同步函数。这意味着它会阻止程序执行并且等候请求服务器的响应。当收到发送请求的响应时,延迟至关重要,这就是禁止从指标调用该函数的原因,因为指标按照交易品种组指标的自己的执行线程操作。在一个图表上执行指标延迟可能导致该交易品种的所有图表停止更新。

该函数只能从专家和脚本调用,因为他们按照自己的执行线程操作。从指标调用,GetLastError() 函数将返回错误4014 �C "函数不允许调用"。

WebRequest() 函数不能在 策略测试中执行。

使用第一版 WebRequest () 函数的示例:

void OnStart()
  {
   string cookie=NULL,headers;
   char post[],result[];
   int res;
//--- 若要启用访问服务器,您应该添加 URL "https://www.google.com/finance"
//--- 在允许的URLs列表(主菜单->工具->选项,标签"EA交易"):
   string google_url="https://www.google.com/finance";
//--- 重置最后的错误代码
   ResetLastError();
//--- 加载谷歌财经的html页面
   int timeout=5000; //--- 低于1000的超时(1秒)不足以缓慢的网络连接
   res=WebRequest("GET",google_url,cookie,NULL,timeout,post,0,result,headers);
//--- 检查错误
   if(res==-1)
     {
      Print("Error in WebRequest. Error code  =",GetLastError());
      //--- 也许URL没有列出,显示需要添加地址的信息
      MessageBox("Add the address '"+google_url+"' in the list of allowed URLs on tab 'Expert Advisors'","Error",MB_ICONINFORMATION);
     }
   else
     {
      //--- 加载成功
      PrintFormat("The file has been successfully loaded, File size =%d bytes.",ArraySize(result));
      //--- 保存数据到文件
      int filehandle=FileOpen("GoogleFinance.htm",FILE_WRITE|FILE_BIN);
      //--- 检查错误
      if(filehandle!=INVALID_HANDLE)
        {
         //--- 保存result[]数组内容到文件
         FileWriteArray(filehandle,result,0,ArraySize(result));
         //--- 关闭文件
         FileClose(filehandle);
        }
      else Print("Error in FileOpen. Error code=",GetLastError());
     }
  }

 

使用第二版 WebRequest () 函数的示例:

#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property script_show_inputs
#property description "Sample script posting a user message "
#property description "on the wall on mql5.com"
 
input string InpLogin   ="";             //您的 MQL5.com 账户
input string InpPassword="";             //您的账户密码
input string InpFileName="EURUSDM5.png"//文件夹 MQL5/Files/的图像
input string InpFileType="image/png";    //正确的图像mime类型
//+------------------------------------------------------------------+
//| 在mql5.com的看板上发布图像信息                                      |
//+------------------------------------------------------------------+
bool PostToNewsFeed(string login,string password,string text,string filename,string filetype)
  {
   int    res;     // 接收操作执行结果
   char   data[];  // 发送POST请求的数据数组
   char   file[];  // 阅读这里的图像
   string str="Login="+login+"&Password="+password;
   string auth,sep="-------Jyecslin9mp8RdKV"// 分段数据分隔符
//--- 文件可用,请读取
   if(filename!=NULL && filename!="")
     {
      res=FileOpen(filename,FILE_READ|FILE_BIN);
      if(res<0)
        {
         Print("Error opening the file \""+filename+"\"");
         return(false);
        }
      //--- 读取文件数据
      if(FileReadArray(res,file)!=FileSize(res))
        {
         FileClose(res);
         Print("Error reading the file \""+filename+"\"");
         return(false);
        }
      //---
      FileClose(res);
     }
//--- 为授权创建POST请求的主体
   ArrayResize(data,StringToCharArray(str,data,0,WHOLE_ARRAY,CP_UTF8)-1);
//--- 重置错误代码
   ResetLastError();
//--- 授权请求
   res=WebRequest("POST","https://www.mql5.com/zh/auth_login",NULL,0,data,data,str);
//--- 如果授权失败
   if(res!=200)
     {
      Print("Authorization error #"+(string)res+", LastError="+(string)GetLastError());
      return(false);
     }
//--- 从服务器请求标题读取授权cookie
   res=StringFind(str,"Set-Cookie: auth=");
//--- 如果没有找到cookie,返回错误
   if(res<0)
     {
      Print("Error, authorization data not found in the server response (check login/password)");
      return(false);
     }
//--- 牢记授权数据,形成进一步请求的标题
   auth=StringSubstr(str,res+12);
   auth="Cookie: "+StringSubstr(auth,0,StringFind(auth,";")+1)+"\r\n";
//--- 如果有数据文件,请将其发送至服务器
   if(ArraySize(file)!=0)
     {
      //--- 形成请求主体
      str="--"+sep+"\r\n";
      str+="Content-Disposition: form-data; name=\"attachedFile_imagesLoader\"; filename=\""+filename+"\"\r\n";
      str+="Content-Type: "+filetype+"\r\n\r\n";
      res =StringToCharArray(str,data);
      res+=ArrayCopy(data,file,res-1,0);
      res+=StringToCharArray("\r\n--"+sep+"--\r\n",data,res-1);
      ArrayResize(data,ArraySize(data)-1);
      //--- 形成请求标题
      str=auth+"Content-Type: multipart/form-data; boundary="+sep+"\r\n";
      //--- 重置错误代码
      ResetLastError();
      //--- 发送图像文件到服务器的请求
      res=WebRequest("POST","https://www.mql5.com/upload_file",str,0,data,data,str);
      //--- 检查请求结果
      if(res!=200)
        {
         Print("Error sending a file to the server #"+(string)res+", LastError="+(string)GetLastError());
         return(false);
        }
      //--- 接收上传到服务器的图像的链接
      str=CharArrayToString(data);
      if(StringFind(str,"{\"Url\":\"")==0)
        {
         res     =StringFind(str,"\"",8);
         filename=StringSubstr(str,8,res-8);
         //--- 如果文件上传失败,将返回空链接
         if(filename=="")
           {
            Print("File sending to server failed");
            return(false);
           }
        }
     }
//--- 创建在服务器上发布图像的请求主体
   str ="--"+sep+"\r\n";
   str+="Content-Disposition: form-data; name=\"content\"\r\n\r\n";
   str+=text+"\r\n";
//--- 在mql5.com上将提供发布帖的语言
   str+="--"+sep+"\r\n";
   str+="Content-Disposition: form-data; name=\"AllLanguages\"\r\n\r\n";
   str+="on\r\n";
//--- 如果图像已经上传到服务器,通过它的链接
   if(ArraySize(file)!=0)
     {
      str+="--"+sep+"\r\n";
      str+="Content-Disposition: form-data; name=\"attachedImage_0\"\r\n\r\n";
      str+=filename+"\r\n";
     }
//--- 多部分请求的最后字符串
   str+="--"+sep+"--\r\n";
//--- 一个字符串中同时输出POST请求主体
   StringToCharArray(str,data,0,WHOLE_ARRAY,CP_UTF8);
   ArrayResize(data,ArraySize(data)-1);
//--- 准备请求标题  
   str=auth+"Content-Type: multipart/form-data; boundary="+sep+"\r\n";
//--- 在mql5.com的用户看板上发布信息的请求
   res=WebRequest("POST","https://www.mql5.com/ru/users/"+login+"/wall",str,0,data,data,str);
//--- 成功执行返回true
   return(res==200);
  }
//+------------------------------------------------------------------+
//| 脚本程序开始函数                                                   |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- 在mql5.com发布信息,包括图像,从InpFileName参数的路径
   PostToNewsFeed(InpLogin,InpPassword,"Checking the expanded version of WebRequest\r\n"
                  "(This message has been posted by the WebRequest.mq5 script)",InpFileName,InpFileType);
  }
//+------------------------------------------------------------------+