1c 8.3 post request to receive orders. Handling http request redirection

A task arose about transferring data between 1C (development and configuration was outsourced), which is planned to be used as the main electronic document management system (EDF) and a B2B system (internal development), which is written in PHP (Symfony) and performs the functions of primary information input into companies.

I already had experience integrating a B2B with another B2B. The idea was to transfer JSON using cURL. Then the task of integrating the Borlas system, based on Oracle, arose, where this approach was also applied. On the Oracle side, however, they used their own package - an analogue of cURL in PHP (if there is interest, I can describe it in a new article).

As I found out, 1C 8.2 can also send GET and POST requests. I assumed that if everything was already configured and works with other systems, then it should work here too. JSON was rejected by 1C developers, saying that the format was inappropriate and they only recognized XML. Comments that this would give us a minimum amount of data transfer, but we actually received a lot of data, were rejected. As a result, we started preparing 2 XML-based systems.

For my part, I wrote a request acceptor from 1C and returned results. A function for receiving a variable in POST, in which 1Sniki had to substitute XML.
The format is approximately the following:

123ABC456//authorization key get_last_orders//operation they want to perform 4000//limit of records that they want to select

A handler that returns records that have already been selected according to the conditions and generates XML like:

1 O.P.S. 4853352 01.01.2013 1 Uploaded from b2b SNILS 999999999 Client's full name Mikhailov Mikhail Evgenievich Date of application 01.01.2013 ...

Data can only be transmitted via an HTTPS connection.

At first glance, everything seems simple, but several problems arose in the process:
1) the outsourcers reported that they were unfamiliar with requests of this kind, and tried to offer an old proven scheme:
1. import file from B2B,
2. Loading into 1C,
3. Export a file indicating what was able to be processed, what was not from 1C,
4. Import to B2B,
5. and from the very beginning...
The scheme was rejected because it needed to be done quickly, and without human intervention and any “buttons.”

Then they asked for a code example. I Googled the following example on the Internet:

Server = "test.com"; Port = "443"; HTTPTry = New HTTPConnection(Server, Port, True); Else HTTP = New HTTPConnection(Server, Port); endIf; ScriptAddress = "/gateway/GetData1C/"; Attempt HTTP.SendForProcessing(SendFileName, ScriptAddress, ResponseFileName, HTTPHeader); Exception Report("Connection attempt failed: " + ErrorDescription()); ElseLogRecord("HTTPConnection", LogLevel.Error, "Connection attempt failed: " + ErrorDescription()); EndIf Return; EndAttempt;

Data began to arrive on the server, but it was empty, that is, GET and POST were empty. I added an entry to the logs and successfully forgot about it. After 4 months, I was given an urgent task - to bring the integration to a result (since a lot of time has passed, 1C developers are working and working, but nothing comes in response). They installed 1C for me and I started poking around.

First, I decided to install Fiddler to understand what was happening. I noticed that the connection is via HTTP, and then the server redirects to HTTPS. I assumed that for this reason the data is empty. I tried to reproduce it in Chrome, and received confirmation that the data in the POST request is lost during the redirect.

Since it is impossible to allow work via HTTP, I began to study why, because it is indicated that:

HTTP = New HTTPConnection(Server, Port, True); The “True” parameter means to use HTTPS, and then it came to light that HTTP = New HTTPConnection(Server, Port);

As a result, this “Otherwise” was thrown out, and I received an error that the certificate was incorrect. The certificate was self-signed. The integration development was carried out on internal servers, where a certificate from “Thawte SSL CA” was officially purchased, in contrast to the PROD server. Importing the certificate into all possible stores did not produce any results.

A search through resources led to the fact that 1C has its own root certificates, and based on them it already checks the others. They are in test form in the file “cacert.pem”, which is located in the “bin” folder, where 1C is located. Import is not as simple as it turned out.

First, we need to export the certificate we need to a file (I already had it in my personal storage). By running “certmgr.msc”, having found the certificate, we export it to a *.cer file.

C:\OpenSSL-Win64\bin>openssl x509 -inform der -in C:\fiddler.cer -out C:\fiddler.pem -text -fingerprint -md5 WARNING: can"t open config file: /usr/local/ ssl/openssl.cnf MD5 Fingerprint=13:BF:73:43:BB:69:19:BA:22:5D:C7:2E:44:85:91:7F
We save MD5, we will need it.
Next, open the file “cacert.pem”.
We go down to the very bottom and add first MD5, and then all the contents that came out in the “fiddler.pem” file.
Save the file.
We restart 1C (maybe it’s not necessary, but it didn’t work for me, so I restarted everything.

The source file in 1C was given this form:

Procedure SendRequestPress(Element) Connection = GetHTTPConnection(); If Connection = Undefined Then Report("Could not connect to the server specified in the exchange settings! Processing was interrupted!"); Otherwise Source = FileAddress; endIf; FileName = FileResult; PostFileName = PostFile; PostFile = New File(PostFileName); SubmissionFileSize = XMLString(SubmissionFile.Size()); Headers = New Match(); Headers.Insert("Content-Type", "application/x-www-form-urlencoded"); Headers.Insert("Content-Lenght", SubmissionFileSize); Attempt Connection.SendForProcessing(PostFileName, Source, FileName, Headers); Exception Report(ErrorDescription()); EndAttempts EndProcedures Function GetHTTPConnection() Export AttemptConnection = New HTTPConnection(HTTPServer,"443",True); Exception Report(ErrorDescription()); Connection = Undefined; EndAttempt; Return Connection; EndFunctions Procedure OnOpen() HTTPServer = "test.com"; FileAddress = "/gateway/GetData1C"; PostFile = "C:\POST_1C\post.txt"; FileResult = "C:\POST_1C\result.xml"; End of Procedure

After clicking the button, a request was sent via HTTPS and the correct XML was received as output.

I looked for how 1C works over HTTPS, a lot of material, but I couldn’t find how to work using a self-signing certificate.

When developing a procedure for sending information from 1C to the site with platform version 8.3.9.2170, I encountered a problem: the site developer provided me with the ability to record the necessary information only using an HTTP request using the PUT method.

Without thinking twice, I sketched out a simple code:

Connection = New HTTPConnection("www.mysite.ru"); Headers = New Match; Headers["Content-Type"] = "application/x-www-form-urlencoded"; Request = New HTTPRequest("/api/order_items/93076?order_item=30", Headers); Connection.Write(Request);

Based on the results of execution, the quantity of goods received at the warehouse should have been entered in the corresponding line of the buyer’s order on the website.

However, as you probably already understood, nothing happened. After I made sure that there were no errors on the site (by sending a similar request through a Chrome plugin), I launched it on my local computer web server and began to experiment.

A strange thing immediately became clear: The above code does not generate a PUT, but a HEAD request!

In the Apache logs I saw the following:

127.0.0.1 - - "HEAD /api/order_items/93076?order_item=30 HTTP/1.1"

I was a little surprised (after all, the manual said PUT in black and white), but I wasn’t confused - you can call the method directly:

Connection.CallHTTPMethod("PUT",Request);

The logs show the same thing:

127.0.0.1 - - "HEAD /api/order_items/93076?order_item=30 HTTP/1.1"

"Maybe I'm doing something wrong?" - I asked myself a question. But there were no hints on the Internet or in the manuals. Well, no one has yet canceled the method of scientific poking. To begin with, I tried doing this:

Connection.CallHTTPMethod("fyvfyv",Request);

In the logs I received:

127.0.0.1 - - "?????? /api/order_items/93076?order_item=30 HTTP/1.1"

Curiously, it means that 1C replaces the PUT method specifically (why did 1C not like it?).

After a few more tries I came up with this:

Connection.CallHTTPMethod("PUT",Request);

In the logs I received:

127.0.0.1 - - "PUT /api/order_items/93076?order_item=30 HTTP/1.1"

And this option has already worked on the site and everyone was happy.

He suggested a more correct solution to the problem: you need to specify a request body, any body, even empty. For example, this option will work:

Connection = New HTTPConnection("www.mysite.ru"); Headers = New Match; Headers["Content-Type"] = "application/x-www-form-urlencoded"; Request = New HTTPRequest("/api/order_items/93076?order_item=30", Headers); Request.SetBodyFromString("",TextEncoding.UTF8, UseByteOrderMark.NotUse); Connection.Write(Request);

And it’s probably quite correct to pass the parameter values ​​themselves in the body of the request.

The conclusion is as follows: the 1C platform considers a PUT request without a body to be erroneous and replaces the method with HEAD.

It is curious that 1C does not track a POST request without a body and does not turn it into a GET, I checked it for fun.

As the well-known Vovochka would say from the famous joke: “Where is the logic?”

I hope my publication will save someone several hours of their life in search of an answer. =)))

Print (Ctrl+P)

You can watch the second part

General information

In platform version 8.3.5.1068 , published in September 2015, a mechanism for integrating 1C with external programs through technology REST interface. The platform uses the OData protocol as an access protocol. It is an open web protocol for querying and updating data. It allows you to manipulate data using HTTP commands as requests. In version 8.3.5.1068 it was possible to receive answers only in the format Atom/XML . However, starting with release 8.3.8.1652 in August 2017, a second option appeared for receiving data in JSON (JavaScript Object Notation) format. . Compared to XML, it is easy to read by people and takes up less space. In addition, all browsers have built-in tools for working with JSON.

Working with the OData protocol on the 1C: Enterprise platform can be found in the book 1C: Developer's Guide in Chapter 17 Mechanisms of Internet services, paragraph 17.2.1 Standard OData interface. You can also look at examples of extending support for the OData protocol,

Advantage of using REST interface. concludes that in order to gain access to system data from an external application, modification of the application solution code is not required (for example, if the application solution is supported). To obtain this access, you must publish the application to the Web server in a specific way and specify which configuration objects will be used in this way. Third-party systems can then access your application using HTTP requests.

Publishing the standard OData interface is performed using the publishing dialog on the web server (Administration - Publishing to web server) and described in the book 1C:Enterprise 8.3. “Administrator's Guide”.
Important! In order for configuration objects to be accessible through the standard OData interface, this must be enabled using the global context method SetComposition ofStandardInterfaceOData().
The mechanism for setting the composition of objects available using the standard OData interface can be done in the form external processing. This does not require modification of the application solution.

To interact with an external REST web server from 1C:Enterprise, we use the tools available in the platform for working with HTTP: objects HTTPConnection, HTTPRequest and HTTPResponse.

In this series of articles, I will show examples of typical operations using the corresponding HTTP method;

  • Receiving data - method GET;
  • Creating an Object - Method POST;
  • Update data: method PATCH– in this case, you can specify only those properties that need to be updated; method PUT– in this case, it is necessary to indicate all the properties of the entity;
  • Deleting data - method DELETE.

1. Examples of data acquisition. HTTP GET method

The server will be a database published on the web server with the name WebBuh(Demo database “Enterprise Accounting 3.0”). I will use the JSON format as the data exchange format. More information about working with JSON is written in the documentation available. To receive data from the server using the HTTP GET method, you need to create an object Reading JSON to read JSON data sequentially from a file or string. To organize sequential recording of objects and texts on the server using the HTTP POST PATCH PUT method, you need to create an object JSON entry. Note that the DELETE method does not require JSON.

To illustrate the flow of reading and writing JSON when accessing the REST interface, I will call the following custom function general purpose Call HTTPMethodOnServer :

&On server // <Описание функции>// // Options: // - A string containing the name of the HTTP method for the request ("POST"."PATCH", "PUT" ,"GET","DELETE" // - HTTPConnection object //<АдресРесурса>- String of the http resource to which the HTTP request will be sent. //<ОтправляемыеДанные>- A structure or match containing data sent to the specified address for processing // on the server using the specified HTTP method "POST" or "PATCH" or "PUT" // Return value: // The structure of the server response depending on the HTTPMethod// Function Call HTTPMethodOnServer(HTTPMethod, HTTPConnection, ResourceAddress, SentData = Undefined ) // Create an HTTP Request Headers = new Match(); Headings.Insert("Content-Type", "application/json"); HTTP Request = New HTTP Request ( ResourceAddress, Headers ); // Write Json to create and update data If HTTPMethod = "POST" or HTTPMethod = "PATCH" or HTTPMethod = "PUT" Then JSON Record = New JSON Record ; ParametersJSON = New ParametersRecordsJSON(Line WrapJSON.Auto,"",True); RecordJSON.SetString(ParametersJSON); WriteJSON(WriteJSON, SentData ); // SentData are required in this case LineForBody = RecordJSON.Close(); RequestHTTP.SetBodyFromString(StringForBody, TextEncoding.UTF8, UsingByteOrderMark.Do Not Use); endIf; // Call the HTTPConnection Method ResponseHTTP = HTTPConnection.CallHTTPMethod(HTTPMethod, HTTPRequest) ; Answer Structure= New Structure ; Answer Structure.Insert("StatusCode", ResponseHTTP.StatusCode); // Read JSON for GET method only If HTTPMethod="GET" Then TryReadJSON = NewReadJSON ; ServerResponse = ResponseHTTP.GetBodyAsString("UTF-8"); ReadJSON.SetString(ServerResponse); Match = ReadJSON(ReadJSON,True); Response Structure.Insert("ServerResponse",Correspondence) ; Answer Structure.Insert (" Server ResponseUndecrypted", ServerResponse); Exception Report(ErrorDescription()); Return Undefined; EndAttempt; EndIf ; Return Answer Structure ; EndFunction // Call HTTPMethodOnServer()

To receive from the server in JSON format when accessing the REST interface of an application solution, you need to specify in the resource address $format=json. Or specify the MIME type "application/json" in the title:

Headers = new Match(); Headings.Insert("Content-Type", "application/json") ; ResourceAddress = " WebBuh/odata/standard.odata/ ?$format=json" RequestHTTP = New HTTPRequest(ResourceAddress, Headers);

Feature of the global context ReadJSON(ReadJSON, True)

  • If the second parameter is set to True, read the object JSON will be completed in Correspondence.If set to False, objects will be read into an object of type Structure.
  • When deserializing JSON objects into a structure, you need to be aware of the structure key requirements. If, when deserializing an object, a property name is found that is not valid for a structure key, an exception will be thrown.

1. 1 Configuring HTTP connection parameters

To organize the client part of interaction with an external REST web server, I created a client configuration based on the BSP from scratch. Using this configuration, I created a reference for setting up connection parameters (see Fig. 1)

Fig. 1 Directory for setting parameters for HTTP connection to external information security via the rest interface

After pressing the button Check the server response, a procedure is called in which the client will try to receive a response from the server. Program code The procedure is written below:

&OnClient Procedure CheckConnection(Command) Address = Object.ServerAddress; User = Object.User; Password = Object.Password; DatabaseName = Object.Name; Port = ? (Object.Port<>0,Object.Port,80); HTTPConnection = New HTTPConnection(Address, Port, User, Password); ResourceAddress = DatabaseName + "/odata/standard.odata/ $metadata "; //Call custom function Answer Structure= B Call HTTPMethodOnServer("GET" , HTTPConnection, ResourceAddress) ; If Answer Structure <> Undefined Then General PurposeClientServer.NotifyUser("Status Code"+Response Structure.Status Code); Endless; End of Procedure

The purpose of this procedure is checking the service and whether the user entered the connection parameters correctly. To do this, just perform a GET request:
HTTPConnection.CallHTTPMethod( "GET", HTTP Request);
using the resource address:
ResourceAddress =BaseName+ /odata/standard.odata/ “;
You can also check the service in your browser using
URL
http://host/WebBuh/odata/standard.odata. The result of such a query is only a list of entities. To obtain a complete description of the standard OData interface (list of available entities, their attributes and functions in the form of XML-
document.) you must perform a GET request using the parameter $metadata. URL http://host/WebBuh/odata/standard.odata/$metadata. Detailed description The document can be obtained at http://www.odata.org/documentation/ (in English).
You can receive answers in the format Atom/XML or JSON. HTTP response status codes can be viewed Responses in the ranges:

  • 100-199 – informational responses indicating that the client’s request has been accepted and is being processed.
  • 200-299 – means that the client’s request was processed successfully.
  • 300-399 means that the request was not completed and the client needs to take some action to satisfy the request.
  • 400-499 – informs about errors on the client application side. These codes may also indicate that additional information is required from the client.
  • 500-599 - Informs about a server-side error, indicating that the server has encountered an error and will likely be unable to fulfill the client's request.

1.2 Searching for an object by ID

The next function is designed to search for a directory or document by a unique identifier on the server. If the object is found, then the function returns the string value of the identifier (Ref_Key), otherwise it returns undefined. The following parameters are passed to the function:

  • HTTPConnection – Object of type HTTPConnection
  • PublicationName – The name of the published server database
  • Element – ​​object entity identifier, for example, Catalog_Organizations or Document_- directory of the Organization.
  • Identifier – The identifier of the object to be searched on the server, e.g. Organization.UniqueIdentifier()
&OnServer Function SearchObjectByGUID (HTTPConnection,PublicationName,Element,UniqueIdentifier) GUID = String(UniqueIdentifier); // convert to the string ResourceAddress = + Element+ "(guid""+ GUID+ "")?$format=json" ; Answer Structure = BCall HTTPMethodOnServer("GET" , HTTPConnection, ResourceAddress) ; If Answer Structure .StatusCode >= 400 Then //General PurposeClientServer.NotifyUser(Element+ "Error"+ResponseStructure.StatusCode+ //GeneralPurposeClientServer.NotifyUser(ResponseStructure.ServerResponseUndecrypted); Return undefined; EndIf ; Match = Answer Structure. ReplyServer a; Array = Match["value"]; If Array = Undefined Then Return Match["Ref_Key"] Else Return Array["Ref_Key"]; endIf; EndFunction

Parameter ResourceAddress used to access a REST service. To check the operation of the service, you can specify the resource in the browser like this

http://(WebServerAddress)/(PublicationName)/odata/standard.odata/(Element)?(Parameters) ,Where

  • WebServer Address– The address of the web server on which the service is published, for example Localhost
  • NamePublications- Name information base indicated when publishing the decision
  • /odata/standard.odata/ – Sign of access to the standard OData interface
  • Element – resource identifier or predefined resources. For example, Catalog_Account(guid’value’).
  • Options– resource parameters. Used, for example, for selection, in the accepted way for HTTP requests: ?key=value&key2=value2

1.3 Searching for an object using search fields

The following user-defined function is designed to search for an object by search fields in the case where the object is by identification number. Function objects string Ref_Key –an identification number.

&OnServer Function P searchObjectBySearchFields(HTTPConnection,PublicationName,Element,SearchFields) Condition = "" ; For Each KeyValue From Search Field Loop Condition = Condition + KeyValue.Key+ "eq"" + KeyValue.Value+ "" and "; EndCycle; Request Text =Lev(Condition, StrLength(Condition)-5); // remove the last 5 characters ResourceAddress= PublicationName+ "/odata/standard.odata/" +Element+ "?$filter=" + Request Text+ "&$format=json& $select=Ref_Key" ; //Call my custom function Answer Structure= CallHTTPMethodOnServer( "GET",HTTPConnection,ResourceAddress); If Answer Structure .StatusCode >= 400 Then //General PurposeClientServer.NotifyUser(Element+ "Error"+ResponseStructure.StatusCode); //General PurposeClientServer.NotifyUser(ResponseStructure.ServerResponseUndecrypted); Return undefined; endIf; Match = Answer Structure. ReplyServer a; Array = Match["value" ]; If Array = Undefined Then Return Match ["Ref_Key" ] Else Return Array ["Ref_Key" ]; endIf; EndFunction

As can be seen from the body of the procedure P searchObjectBySearchFields, selection starts with the keyword$filterin the resource address. Formal parameterSearch Fields –this is a correspondence that contains the names and values ​​of the details.

Please note that the names of the details are sometimes not obvious. It is necessary to remember that for reference books:

  • Code - code,
  • Description – Name
  • DeletionMark – deletion mark,
  • IsFolder – group sign,
  • Parent_Key – parent.
  • If the attribute is of a reference type, the _Key suffix should be added to its name, for example Account_Key.

For documents:

  • Number – document number,
  • Date – document date.

Logical selection operations

  • eq - Equal; /Catalog_Cities?$filter=Name eq ‘Main’;
  • ne - Not equal; /Catalog_Cities?$filter=Name ne ‘Perm’;
  • gt - More; /Catalog_Products?$filter= Price gt 10;
  • ge - Greater than or equal to; /Catalog_Products?$filter=Price ge 10;
  • lt - Less; /Catalog_Products?$filter=Price lt 10;
  • le - Less than or equal to; /Catalog_Products?$filter=Price le 10;
  • or - Logical OR; /Catalog_ Products ?$filter= Price lt 10 or Price gt 100;
  • and - Logical AND; / Catalog _Products?$ filter =Price g t 10 and Price l t 100;
  • not - Negation; /Catalog_ Products ?$filter=not (Price eq 10);

Note also that the value of the actual parameter Element(or entity)) which I pass to the function is formed according to the following rule:

Name Prefix_ConfigurationObjectName_Name Suffix.

Using the standard OData interface, you can access the following objects ( Name Prefix):

  • Directory - Catalog;
  • Document - Document;
  • Document Journal - DocumentJournal;
  • Constant - Constant;
  • Exchange plan - ExchangePlan;
  • Chart of accounts - ChartOfAccounts
  • Chart of calculation types - ChartOfCalculationTypes;
  • Characteristic types chart - ChartOfCharacteristicTypes;
  • Information Register - InformationRegister;
  • Accumulation Register - AccumulationRegister;
  • Calculation register - CalculationRegister;
  • Accounting Register - AccountingRegister;
  • Business process - BusinessProcess;
  • Task - Task.

ConfigurationObjectName- the “Name” property of the configuration object as it is specified in the configurator.

Name Suffix- needed to clarify the resource name, optional, can take the following values:

  • The name of the tabular part of the object;
  • Name virtual table object;
  • RowType - row of the tabular part of the object;
  • RecordType - a separate register entry.

Parameters for accessing resources

After forming the resource name, you need to define the parameters for accessing the resource, for example, ?$filter= Meaning &$format=json& $select= Ref_Key ,

  • $filter- selection when receiving data
  • $format- indicates the format of the returned data,
  • $select- listing of entity properties that will be included in the query result;
  • $metadata- returns a description of the standard OData interface (used without specifying a name suffix, example in one of the images above);
  • $top- limiting the number of records returned;
  • $skip- removes the specified number of records from the query result;
  • $count- returns the number of records in the query selection;
  • $inlinecount=allpage(=none)- adds information about the number of records to the query result
  • $orderby=<Реквизит1>asc,<Реквизит2>desc- sorting the query result
  • allowOnly- only allowed ones (used without the “$” sign).

1.4 Get an array of information register entries

Let's look at an example of obtaining an array of register entries for information about full names of individuals, for example, the history of changes in full names individual

NamePublications = "WebBuh"; Element = "InformationRegister_Name of Individuals"; Period = Undefined; ReferenceType Data= new Structure(); D DataReferenceType.Insert("Individual",Individual_Key); DataNON-ReferenceType= new Structure(); DataNON-ReferenceType.Insert("Individual_Type", "StandardODATA.Catalog_Individuals") Array = GetRegisterInfoSet(HTTPConnection,PublicationName,Element,Period, DimensionsReferenceType, Non-ReferenceType Dimensions)

The body of the GetInfoRegisterRecordSet function, which is called in this example, is shown below

&OnServer Function GetSetRecordRegisterInformation(HTTPConnection,PublicationName,Element,Period =Undefined, DimensionsReferenceType= Undefined Non-ReferenceType Dimensions= Undefined) RequestText = "" ; If Period<>Undefined Then FormattedPeriod= Format (Period,"DF=yyyy-MM-ddTHH:mm:ss"); RequestText = "Period = datetime"" + FormattedPeriod + """ ; endIf; If DimensionsReferenceType <>Undefined Then For Each KeyValue Of DimensionsReferenceType Cycle Powered = ? ( ValueFilled(QueryText), "," ,""); RequestText = RequestText+ Powered up + KeyValue.Key+ "=guid(""+ KeyValue.Value+ "")"; EndCycle; EndIf; If Non-ReferenceType Dimensions<> Undefined Then For Each KeyMeaning Of Non-ReferenceType Dimensions Cycle Asked = ? ( ValueFilled(QueryText), "," ,""); QueryText = QueryText + Fed+ K keyMeaning.Key + "=" + KeyValue.Value; EndCycle; endIf; ResourceAddress=PublicationName + " /odata/standard.odata/" + Element + "("+ Query Text + + ") ?$format=json"; //Call my custom function Answer Structure = Call HTTPMethodOnServer("GET",HTTPConnection,ResourceAddress); If Answer Structure.StatusCode >= 400 Then//General PurposeClientServer.NotifyUser(Element+ "Error"+ResponseStructure.StatusCode); //General PurposeClientServer.NotifyUser(ResponseStructure.ServerResponseUndecrypted); Return undefined; endIf; Match = 0

Starting from the second version 8 of the platform, users and developers have the opportunity to use http request directly in 1C. The program supports two types of requests:

  • POST requests;
  • GET requests.

Thus, a fairly convenient tool was created for exchanging data and interacting with web services and services operating via http.

GET request

Of course, the simplest examples of using queries illustrate their capabilities much better than many lines of description. So let's try:

  1. Let's get the body of the main page of our site;
  2. We will work on redirecting the request;
  3. Let's take the picture from the site.

Getting the site body

Let's start with something simple. In Fig..

The result of executing this section of code is a fairly large text, the final section of which is shown in Fig. 2.

Fig.2

In the first line of code we create a connection object to the http resource. An object can contain the following properties:

  • Server - connection string containing the server address;
  • Port – contains a number indicating the server port; by default, depending on the connection type, you can specify 80 for unsecured connections or 443 for SSL secured ones.
  • Username – indicated if authorization on the server is required;
  • Password – user password on the specified resource;
  • Proxy – can contain an object of the InternetProxy type, indicated when a proxy is used to communicate with the server;
  • Secure Connection – default value is FALSE, switching to TRUE indicates the use of the https protocol.

In addition, the HTTPConnection object has its own methods, calling which allows you to more fully describe the handler execution algorithm:

  • CallHTTPmethod – contains two required parameters, HTTPmethod and HTTPrequest, supports the ability to write the response body to the file specified in the third parameter;
  • Write – using a PUT request, sends data to the server;
  • Modify – modifies an object by processing PATCH requests;
  • SendForProcessing – a method indicating the use of a POST request, as in all previous methods, must contain the text of the request, and can also transmit the address of the response file for recording data;
  • Receive - this will be discussed in more detail below;
  • GetHeadings is another method that will be used in the article;
  • Delete is actually a Delite request that removes the resource passed in the request from the server.

In the second line we create a request to the selected site, the text of our request contains one slash, which means that we want to receive home page. If the slash were followed by any expression, for example “page2” or “news”, we would get a different page.

The third line executes our request to the server.

In the fourth we show the result.

Handling http request redirection

Let's imagine a situation where we need to programmatically get a search result through any search engine by the key “Requests in 1s”. The section of code required to access GOOGLE is shown in Fig. 3

Fig.3

Here, in addition to the structures already familiar to us, there are Headers and Status Code. Let's deal with them.

Status Code – standard value specified in “Request for Comments”, can take the following values:

  1. If everything is fine, the value will return in the range from 100 to 299;
  2. In case of redirection, a code in the range from 300 to 399 will be returned; in our case, a successful permanent redirection to a resource will be determined by code 301;
  3. If there are errors in the request, the parameter will take a value from 400 to 499;
  4. A value in the range 500-599 indicates problems with the server.

Each page has a title, in the text of which several parameters can be distinguished (Fig. 4):

  1. Connection diagram (everything that comes before two slashes “//”);
  2. Address bar connections;
  3. Username and password;
  4. Port and host to connect to.

It is this splitting that is performed by the SplitAddressLine function. Having thus received new address, we can save the page on our computer and open it in the default browser (GetPage procedure).

Fig.5

There are no new functions or ways to work with requests here, we are actually creating Text Document from the body of the site and launch the page in the browser.

We place the file at the root of drive D and call it test.

We take the image from the site

A natural question arises: if we do not need the entire site, but only need to obtain its individual elements, can this be done and how? Yes you can. The program code that allows you to do this is presented in Fig. 6

Fig.6

As you can see from the figure, in the body of the request we have the code of the site structure element that we need to receive. This part was not in our previous description and we need to dwell on this point in more detail.

We used a browser Opera to access the site. It has one important tool for us: when you right-click on an element, you can call up a context menu, one of the items of which is “View element code”.

It is thanks to him that we can obtain the address that will be used in the request Fig. 7.

POST request

Unlike simple Get requests, POST http requests have a text body that can be stored as in a regular text form, and in the form of files with the extension xml, soap, json. There are quite a lot of tools on the network for creating request texts that allow you to debug and monitor the execution of certain requests.

In 1C, in order to launch a request with a specific text, the HTTP request object has the SetBodyFromString procedure.