ISAPI wonderful programming

xiaoxiao2021-03-06  47

I used to do a little ISAPI program. I have been looking for a long time for a long time. I didn't write it all. After two months of exploration, I finally did something. For a long time, I always wanted to write an article about ISAPI, but I haven't had time, I have time to write a lot of time, I have written recently, I will return it. Slightly thinking, want to write the following: 1. ISAPI Description 2, a simple ISAPI program 3, ISAPI implementation client / server interaction 4, ISAPI Operation Database 5, using ISAPI for network data transmission 6, ISAPI transmission data encryption 7 , ISAPI network data transfer advancement (network big data package transfer) 8, summary

First, ISAPI Introduction

General Gateway Interface CommongatewayInterface (CGI) has been widely used as a standard for interactive web applications in the Internet. The CGI script allows people to write simple applications with multiple programming languages ​​(such as Basic, C, Perl, Shell, etc.). These scripts are running on the web server and output running results on the customer's web browser. The customer's input is passed through an environment variable or a standard input device, and then the CGI program completes a specific operation as needed, and displayed in the customer's browser via HTML format. This feature of CGI brings a vitality to the Internet, and the construction of the website has also become a warm girl from the silence of the scene, and the Snow White, the Snow White, is also increasingly tired. People in long-term use still discover a large disadvantage of the CGI application: the performance is not high. Every time I request a CGE program, the CGI execution file (or script interpreter) must create a new process for each request. For sites that are relatively large, this is undoubted to add a heavy burden to the server. In the years, the lively Internet has introduced ASP, JSP and other measures to improve safety and server performance, and the maturity of the security and development tools is far less than the success of VC, Delphi, etc., and as a Familiar with software programmers, using ready-made development tools and existing resource development, a website system is more powerful.

ISAPI (Internet Server Aplication Programing Interfase) is developed with a programming tool, a standard programming interface that runs in NT services, and web developers can use it to write interactive applications. The ISAPI extension application has the same functionality of CGI scripts, but it has faster and more efficient than CGI. ISAPI for Windows NT written, web users can activate the application by filling in an HTML form (FORM) or click on the link on the HTML page on the Web node. After the server is acquired, the activated ISAPI application processes the obtained information. The data in accordance with the ISAPI application or stores the acquired information into the database, or to obtain data in the database, and then send the result in the form of the HTML page back to the client. Isapi's application is compiled as a dynamic link library (DLL, DYNAMIC Linked library), which is loaded in the WWW service (Service) starts in memory. It requires less system overhead, which is significantly better than CGI applications. Because each request does not start a separate process. For interactive procedures with CGI, each request needs to start a separate process.

Isapi has a significant performance advantage, but its debugging does not have fewer development materials, and has always become a cause of developers. In order to use iSAPI more widely, special as this article, for the majority of developers to enter the development process faster. return

Second, a simple ISAPI program

New, Object, isapi extension wizard, Object Name gives a firstisapi, ok, the second step is not changed, point FINSHED is complete. Press F7 to put the generated DLL in the C: / INETPUB / WWWROOT / FIRSAPI directory (don't use me to teach it?), Open your browser, enter http://127.0.0.1/firstisapi/firstisapi in the address bar .dllok We can see the following: this default message. If you see the above English characters, your server can be used. If you see a download file dialog, don't cry! Explain that your server is not configured, let's take a step by step, don't miss this opportunity! Start, program, management tool, Internet service manager, open the left tree, find the firstisapi under the default Web site, and the mouse is marked in the right button, the property, the execution license drop-down list, check the script and executable? Also don't move (if you think it is fun, you can do it, but the server configuration is not good. Don't blame me "declaration :)"). What do we have to do? Forgot, wait! Oh, right , Click OK, if not, you are Chinese version, then sure it! Ok, http://127.0.0.1/firstisapi/firstisapi.dll ------------- ---------- >>>

THIS Default Message Was Produced by The Internet Server DLL Wizard. Edit Your Cfirstisapiextension :: Default () Implementation To change It. This time I saw it? Already? Forget it, don't learn isapi, more trouble, you don't bother me I bother, stinking! (I think about it, this may still have, I still have a person, so that you can just yell, good, open the CD drive, put the 2000 disc, still ? Add a component, reload your Internet service! ...) Will n't you do it? No Chineseq608@163.com OICQ: 67406204http://www.ources.net Contact me, I will Help you !!! ~~~~~~~~~

So, our first ISAPI is made, you can do it, I will do isapi ........--------- fart! This is also called?

Yes, forgot Win98 friends, sorry, have you installed PWS? That pack! Other and 2000 Datong, don't use me? :) :)

return

Third, ISAPI implements customer / server interaction

We can now make a simple ISAPI program, but it doesn't have it, after all, we haven't added the code you move! In CFirstISAPIExtension class as the same general procedure was added to make a member function void Getdata (CHttpServerContext * pCtxt, char * data); then added ON_PARSE_COMMAND (Getdata, CFirstISAPIExtension, ITS_PSTR) between BEGIN_PARSE_MAP (CFirstISAPIExtension, CHttpServer) and END_PARSE_MAP (CFirstISAPIExtension) and ON_PARSE_COMMAND_PARAMS ( "data"), as follows: BEGIN_PARSE_MAP (CFirstISAPIExtension, CHttpServer) // TODO: insert your ON_PARSE_COMMAND () and // ON_PARSE_COMMAND_PARAMS () here to hook up your commands.// For example: ON_PARSE_COMMAND (Getdata, CFirstISAPIExtension, ITS_PSTR)

ON_PARSE_COMMAND_PARAMS ("DATA") ON_PARSE_COMMAND (Default, CfirstisapieXtension, ITS_EMPTY) DEFAULT_PARSE_COMMAND (Default, cfirstisapiextension) end_parse_map (cfirstisapiextension)

ON_PARSE_COMMAND_PARAMS is the parameter map macro, the first parameter of ON_PARSE_COMMAND getData is a function name to handle the event. The second parameter cfirstisapiextension is the application subclass with chttpserver as the parent class, the back parameters to pass the parameters of the getData function. List, they can be: ITS_EMPTY: No data; ITS_PSTR: String; ITS_I2: Short integer; ITS_I4: long integer; ITS_R4: Float floating point; ITS_R8: Double floating point number. The number of parameters is generally corresponding to the parameters parsing the following on_PARSE_COMMAND_PARAMS. We can assign an initial value here when we don't pass the actual values ​​of this parameter in your browser. Such as Data = www.orcode.net; here DATA is the parameter name we have to get in the getData.

With these preparations, we can add code, because it doesn't have something in peaceful programming, so we will simply add a little code to see what we have done for a long time?

as follows:

Void cfirstisapiextension :: getData (chttpserverContext * PCTXT, CHAR * DATA) {

STARTCONTENT (PCTXT); // Write HTML file headwritTitle (PCTXT); // Write title * PCTXT << _t ("This is the data you submitted:
/ r / n"); // To browser Send data * PCTXT << Data << "/ r / n"; // Write a wrap and carriage return ENDCONTENT (PCTXT)

}

ChttpServerContext * PCTXT is a server context sign, we transfer data to your browser. * PCTXT << The string after the browser is the HTML source in the browser, so you can put "this is the data you submitted:
/ r / n "changed to HTML you want, I want to change you! :) Is it going to press F7? Haha, good, f7, immediately put firstisapi.dll ctrl c, ctrl v ........

"Unable to create or replace Firstisapi: The specified file is being used by Windows, can not be?

I will restart computers, who teaches it to load memory! However, you change the DLL to change your name, you have to wait for a smoking company!

The article ISAPI debugging, you can take a look at friends who don't love the old computer. ISAPI is part of IIS at runtime, while IIS is run as a service of NT. This fact has become more complicated using the debugging process, because when the IIS is running, the VC debugger cannot take over ISA. In order to solve this problem, Microsoft has issued IIS in two forms: as a service, as well as a separate executable. For the latter case, we can control the server on the command line. Although this can solve the above problems and make it easy to develop, it is very cumbersome. Let's introduce this process.

When the user is in debug debug mode, VC (and IIS) will run under the user's account and permission. Since some of the works completed in IIS are not allowed to have corresponding permissions, the user (or user system administrator) needs to do the following:

Select "Start / Program / Manage Tools (Public) / Domain User Manager" on the desktop, open the domain user manager; select "User Permissions" in the Rules menu; select "Show Advanced User Permissions" check box; Select "Operation System Mode Operation" in the "Permissions" drop-down list; select the "Add" button to get the Add User and Group dialog box, select the "Show User" button and select the user who uses the user in the "Name" list. Then select the Add button; select the "OK" button; repeat the above steps for the "Generation Security Audit" permission.

In order to take these settings, users must first quit login, and then log in back. The IIS contains three services: ftppublishing service, GopherpublishingService and WorldWideWeb. Since the debugger wants to run IIS on the command line, all three services must be stopped. This can be implemented in the "Services" program in the Control Panel or use IIS's "Internet Service Manager". If you need a lot of debugging, we recommend that users shut down the IIS service through the "Service" program in Control Panel, and prohibit them from starting, so that users should be turned off each time the computer is turned off. Next, the project must be configured: Select the settings menu item in the Project menu; select the debug panel, and select General in the Category drop-down list; enter or find the path to the IIS execution file in the ExecutableFordebugSession box (usually in the case Winnt / System32 / INETSRV / INETINFO.EXE); Enter -EW3SVC in the ProgramArguments box, as shown in Figure 3; Figure 3 Debug panel settings Select the LINK panel; enter the path to the compiled DLL in the OutputFileName box and file name. This path must be in the root directory of the web server or under a virtual target so that the customer can access it through the URL. For example, our directory of our web server is C: / INETPUB / WWWWROOT / FIRSAPI, we put firstisapi.dll in this directory so that customers can use the following URL to access it: http: //127.0.0.1/firstisapi /firstisapi.dll If the user has not exited login to change the permissions, please act now, and then log in back. In this way, our server DLL is very successful, hurry up in the browser http://127.0.0.1/firstisapi/firstisapi.dll?getdata&data= this is the information I sent to the server! OK?

This is the data you have submitted:

This is the information I sent to the server!

OK!

Do we want to submit data to the server in form form?

The following HTML source code is stored as a firstisapi.htm file and placed in the same directory in the DLL.

data to be submitted:

return

Fourth, ISAPI Operation Database

Above we define a getData function, we have implemented such a function in the function: send the data from the customer to the customer. If you operate the database? What kind of truth is the same, we will add actions in your own defined function. The code can be implemented to access the database. The input data is sent to the client using * PCTXT to the browser in the variable Data. Now we create a database, what library is selected by you, can be Access, SQL Server, SBASE, etc., we only use the data source to operate it, we build system data sources after building the library (do not build user data Source? Why? Ask Bill Gats Go to the firstodbc, build a simple table with SQL below. Table: User Data Create Table User_info (ID INT (4) Not Null, Friend_Id Int (4) Not Null, User_Name Varchar (30) Not Null, User_Sex Varchar (2) Not Null, Address Varchar (20), AGE INT (4 ), zip char (6), Phone Varchar (20)) With data sources, we can add code to implement database query, modification, etc. Like the same section, add a member function void REG (ChttpserContext * PCTXT, Char * User_name, char * sex, char * address, intade, char * zip, char * phone) parameters, respectively: User name, gender , address, age, zip code and phone and we want it to achieve the function is the user-submitted data through forms written FirstODBC database. then also joined ON_PARSE_COMMAND (Reg between BEGIN_PARSE_MAP (CFirstISAPIExtension, CHttpServer) and END_PARSE_MAP (CFirstISAPIExtension), CFirstISAPIExtension , ITS_PSTR ITS_PSTR ITS_PSTR ITS_I2 ITS_PSTR ITS_PSTR) and ON_PARSE_COMMAND_PARAMS ("User_name SEX Address = 'Age = 20 Zip =' 'phone ='), as shown below:

BEGIN_PARSE_MAP (CFirstISAPIExtension, CHttpServer) // TODO: insert your ON_PARSE_COMMAND () and // ON_PARSE_COMMAND_PARAMS () here to hook up your commands.// For example: ON_PARSE_COMMAND (Reg, CFirstISAPIExtension, ITS_PSTR ITS_PSTR ITS_PSTR ITS_I2 IITS_PSTR ITS_PSTR) ON_PARSE_COMMAND_PARAMS ( "user_name sex address age zip phone) ON_PARSE_COMMAND (Getdata, CFirstISAPIExtension, ITS_PSTR) ON_PARSE_COMMAND_PARAMS ( "data") ON_PARSE_COMMAND (Default, CFirstISAPIExtension, ITS_EMPTY) DEFAULT_PARSE_COMMAND (Default, CFirstISAPIExtension) END_PARSE_MAP (CFirstISAPIExtension)

Below we define your own functions and perform the database, click on the left Firstisapi Classes, New Class, Name: Cuserset, Base Class: CRecordset ------------- OK, ODBC: FirstBC, Table name: user_info, ok. (Please see if there is a #include in stdafx.h) Void REG (ChttpserverContext * PCTXT, Char * User_name, Char * SEX, Char * Address, Int Age, Char * Zip, Char * Phone )

{// Open database source code startcontent (PCTXT); // Print and tag WRITETITLE (PCTXT); // Print , "Title", and </ Title> Mark and other CDatabase DB; if (! db.open (_T ("first (" Source Name) false, // bexclusivefalse, // BreadOnly_t ("ODBC; UID = SA; PWD =;"), // LpszConnect (with database Connection method) False)) {// busecursorlib * PCTXT << "Could Not open Database."; Return;} CRecordset set (& dB); try {set.open ();} catch (cdbException * pex) {* PCTXT < <_T ("Error Selecting from Table:"); Tchar SzerrorMessage [1024]; IF (PEX-> getErrorMessage (SzerrorMessage)) {* PCTXT << SzerrorMessage; * PCTXT <<_T ("/ R / n ");} return;} set.addNew (); set.edit (); set.m_id = 0; set.m_user_name = user_name; set.m_sex = sex; set.m_address = address; set.m_age = ag; Set.m_zip = zip; set.m_phone = phone; set.Update (); set.close (); db.close (); * PCTXT << _t ("You have successfully registered! / r / n"); / / Print </ body> and </ html> tagged endContent (PCTXT);} Save the following HTML as REG.HTM</p> <p><Html> <body> <center> <font color = '# ff0000'> <h3> Please enter your registration information below (including * is required) </ h3> </ font> </ center> <Hr> <center> <form method = "post" Action = "firstisapi.dll?"> <P align = "center"> </ p> <input type = "hidden" name = "mfcisapicommand" value = "REG > <p align = "center"> Name: <input type = "text" name = "user_name" size = "20"> </ p> <p align = "center"> Gender: <select name = "SEX "SIZE =" 1 "> <option selected value =" 1 "> Male </ option> <option value =" 0 "> Female </ option> </ select> </ p> <p align =" center "> Address: <input type = "text" name = "address" size = "20"> </ p> <p align = "center"> age: <input type = "name =" size = "20 "> </ p> <p align =" center "> Zip: <input type =" text "name =" zip "size =" 20 "> </ p> <p align =" center "> Tetrane: <input TYPE = "text" name = "phone" size = "20"> </ p> <p align = "center"> <input type = "submit" value = "Submit"> </ p> </ form> < / center> </ body> </ html></p> <p>Then put it into the firstisapi directory, ................ http://127.0.0.1/firstisapi/reg.htm This is then entered after entering your data in the browser form. Submit, look at your server database, ha, there is -----------> You have successfully registered !! I want to do a query program, but the time is too tight, or think about it, And there is no different from the registration program, just add a chaxun (...), OK That Is All Right! There are some imperfect places that it is not to verify that the username has been registered, and has not yet arrived. The maximum value. But here is just to demonstrate how to operate the database, the author does not deputy, interested friends you can add this code. return</p> <p>V. Use of ISAPI for network data transmission</p> <p>The so-called network data transmission, briefly, is another computer that transmits data from one computer to the network. Speak data transmission, everyone is the most familiar Socket socket, no matter in UNIX, Windows, it has always been They are all recognized transmission options. After studying ISAPI, the author successfully implemented network data transmission with ISAPI, and solved the effective transmission of data within the local area network firewall. First, we have to establish server data to receive the ISAPI program. In the third We have established a getData (. Char * data) function in the <ISAPI implementation Customer / Server Interaction> In the Data, it is the data we passed from the client. In this function, we can Treatment, such as write files, write databases, etc., then send a receipt to the customer by * PCTXT. About how to write the library write file has exceeded this section, and will not be described here. In the third quarter, we pass the Form form to send the data to the server through the browser, here, we have to send data to the server through our client's program. Add a member function in your program: Bool sendData (Char * ip, char * request, char * buffer, unsigned int bufferlen), where the parameter IP is the server IP address, if it is this machine, incoming 127.0.0.1; Request is the data to be sent to the server, eventually received by getData (), stored in the DATA for server handler processing; buffer is back to the server back to the in-law, ie * PCTXT serial back data bufferlen is buffer 绶 绶Zone length.</p> <p>The Senddata code is as follows: Bool Senddata (Char * ip, char * request, char * buffer, unsigned int bufferlen) {int RET = 0; cstract url; url = "http: //"; URL = (cstract) IP; URL = "/firstisapi/firstisapi.dll?getdata&data=";URL =(CString )Request;///AFXMESSAGEBOX (URL );CinternetSession session; cinternetFile * cf; // ----------- --- Try {CF = (CinternetFile *) session.openurl (URL);} catch (cinternetException * exp) {char Err [1024]; Exp-> getErrorMessage (ERR, 1024, NULL); AFXMessageBox (ERR); CF = NULL; Exp-> delete ();} if (cf) {RET = CF-> Read (Buffer, Bufferlen); cf-> close ();} session.close (); return (re);} In the program, you can call it: void csassdlg :: Onbutton1 () {// Todo: add your control notification handler code herestring ip = "127.0.0.1", DATA = "This is the data I want to send", Buffer BOOL B = Senddata ((char *) LPCTSTR (IP), (char *) LPCTSTR (DATA), BUFFER.GETBUFFER (1204), 1024); if (b) {MessageBox ("Data Send Success");}} In this way, we only need to pass the data to the server to the second parameter of Senddata, the server DATA can be received, how do you want to handle it. return</p> <p>6. ISAPI transmission data encryption</p> <p>In order to improve the security, reliability of data transmission, we have to encrypt the data before data transfer, but no matter which encryption algorithm, encrypted data may have, such as "@ # $% ^ & * - " And inactors, the server is processed when using the ISAPI method, and the server is processed after the on_parse_command and the on_PARSE_COMMAND_PARAMS parameter map macro, such as "%, &" and other characters will be automatically converted or sent as a separator. In this way, the server is received. Data will be wrong. In order to ensure the reliability of data transmission, the author has been studied by many aspects, defines the following two functions, which are previously processed as the client encryption, and the server receives the data post-decryption before decryption. After the client encryption, the prior data processing function: void code (char * buf, int LEN, char * outstr) // encrypted post-processed {CSTRING STR; int outstR_len; outstr_len = 0; char * TMP; TMP = New Char [16 ]; OUTSTR [0] = 0; for (int i = 0; i <len; i ) {TMP [0] = 0; if (BUF [i] == '|| BUF [i] ==' & '|| BUF [I] =='! '|| buf [i] =='? '|| BUF [i] ==' '|| BUF [i] ==' // '|| buf [i] == '/') {str.format ("%%% x", buf [i]); struct (tmp, str); outstr_len = 3;} else {TMP [0] = BUF [i] ; TMP [1] = 0; OUTSTR_LEN ;} if (buf [i] == '$') {struct (tmp, "$$"); outstr_len = 2;} if (buf [i] == 0) { STRCPY (TMP, "$ 0"); OutStr_len = 2;} strcat (outstr, tmp);} return;} where BUF is incoming data 绶绶 pointer, LEN is the BUF data length, Outbuf is processed after processing data storage District. Treatment of special characters and 0 characters such as "%, &, " during processing, so that the data is transmitted to the server, it will be correct, after which the server processing function is restored, then decrypt, then our data Will n't be wrong.</p> <p>The server receives the data post-decryption before decryption: int decode (char * buff, int LEN, char * outstr) // upload post-up processing {INT i, p; char v; p = 0; for (i = 0; i < Len; i ) {IF (buff [i] == '$') {ix (buff [i 1] == '$') {v = '$';} else {ix (buff [i 1] == '0') v = 0;} i ;} else {v = buff [I];} outstr [p] = v; p ;} return (p);} where buff is incoming data 绶绶 pointer The LEN is the length of the buff, and Outstr is processed. Process: Encrypt DATA ------> Code Function Processing --------> The server is connected to DATA -------> Decode for upload processing ------> Decryption</p> <p>Seven, ISAPI network data transfer advancement (network big data package delivery)</p> <p>The author has tried to transmit big data packets with the above method, but this method can only be transmitted less than 2K packets, which is undoubtedly a disadvantage. After many aspects of research, this method is found to transmit data with a GET method, and the operating system itself limits its amount of data. After testing, if you transfer it to the POST method, the size of the sending packet will not be limited. The next section will explain how to send data to the server with the POST method.</p> <p>Bool PostData (Char * IP, Char * Request, Char * OUT_BUF, INT BUF_LEN) {BOOL RET = FALSE; Char * Buffer, * Buff, * Out; Buffer = New Char [2048]; INT BB_LEN = Strlen (Request); BUFF = new char [bb_len]; out = new char [bb_len 1000]; CinternetSession session; chttpfile * pfile = null; chttpConnection * PConnection = NULL;</p> <p>CSTRING M_IP, SQL; M_IP = (cstring) ip; // ---------------------------- Pair of Request Encryption Strcpy (buff, request ); for (int i = 0; i <bb_len; i ) // buff [i] = buff [I] ^ (((i 0x56)% 255); Code (buff, bb_len, out); / / Upload pre-processing // ---------------------------------- SQL = (cstring) Out; CString strheaders = _T ("Content-type: Application / X-WWW-FORM-URLENCODED"); CSTRING STR, StrformData = _T ("DATA ="); strformData = SQL; try {pConnection = session.getttpConnection (m_ip); pfile = pConnection-> OpenRequest (CHttpConnection :: HTTP_VERB_POST, _T ( "/ firstisapi / firstisapi.dll Getdata?")); BOOL result = pFile-> SendRequest (strHeaders, (LPVOID) (LPCTSTR) strformData, strformData.GetLength ()); DWord dwret; pfile-> queryinfostatuscode (dwret); // -------------- if (dwret == http_status_ok) {buf_len = pfile-> read (Buffer, 2048); str = CString) Buffer; str = str.LEFT (buf_len); RET = true;} elseSser = "server handle!"; Pfile-> close (); delete pfile; pconnection-> close (); delete pConnection;} catch CinternetException * pex) {tchar szerr [1024]; pex-> getErrorMessage (Szerr, 1024); str = szerr; pex-> delete (); } There is an accident when catch (...) {str = "and server communication! "} session.close (); strcpy (out_buf, str); buf_len = str.getLength (); MessageBox (NULL, STR, System Tips", MB_OK; delete buff; delete out; return; } The parameter IP is the server IP address. If it is this machine, it is incoming 127.0.0.1; request is the data to be sent to the server, eventually receives, stored in the DATA for server handler; buffer is the server Recurns back the rushing area, that is, * PCTXT serial back data bufferlen is the buffer 绶 区 length.</p> <p>The server receives the program as before, so we can send more than 2K data.</p> <p>return</p> <p>Eight, summary</p> <p>Strong grab time, finally completed, just simple completion, there is also a lot of incorrect places, I hope everyone is used to find mistakes! Thank you!</p> <p>This article can be reflected freely under the premise of retention author copyright.</p> <p>Longfei letter box</p> <p>Ourcode.net Northwest Normal University Normal University Computer Rieseology Website: http://www.orrode.net</p></div><div class="text-center mt-3 text-grey"> 转载请注明原文地址:https://www.9cbs.com/read-79999.html</div><div class="plugin d-flex justify-content-center mt-3"></div><hr><div class="row"><div class="col-lg-12 text-muted mt-2"><i class="icon-tags mr-2"></i><span class="badge border border-secondary mr-2"><h2 class="h6 mb-0 small"><a class="text-secondary" href="tag-2.html">9cbs</a></h2></span></div></div></div></div><div class="card card-postlist border-white shadow"><div class="card-body"><div class="card-title"><div class="d-flex justify-content-between"><div><b>New Post</b>(<span class="posts">0</span>) </div><div></div></div></div><ul class="postlist list-unstyled"> </ul></div></div><div class="d-none threadlist"><input type="checkbox" name="modtid" value="79999" checked /></div></div></div></div></div><footer class="text-muted small bg-dark py-4 mt-3" id="footer"><div class="container"><div class="row"><div class="col">CopyRight © 2020 All Rights Reserved </div><div class="col text-right">Processed: <b>0.038</b>, SQL: <b>9</b></div></div></div></footer><script src="./lang/en-us/lang.js?2.2.0"></script><script src="view/js/jquery.min.js?2.2.0"></script><script src="view/js/popper.min.js?2.2.0"></script><script src="view/js/bootstrap.min.js?2.2.0"></script><script src="view/js/xiuno.js?2.2.0"></script><script src="view/js/bootstrap-plugin.js?2.2.0"></script><script src="view/js/async.min.js?2.2.0"></script><script src="view/js/form.js?2.2.0"></script><script> var debug = DEBUG = 0; var url_rewrite_on = 1; var url_path = './'; var forumarr = {"1":"Tech"}; var fid = 1; var uid = 0; var gid = 0; xn.options.water_image_url = 'view/img/water-small.png'; </script><script src="view/js/wellcms.js?2.2.0"></script><a class="scroll-to-top rounded" href="javascript:void(0);"><i class="icon-angle-up"></i></a><a class="scroll-to-bottom rounded" href="javascript:void(0);" style="display: inline;"><i class="icon-angle-down"></i></a></body></html><script> var forum_url = 'list-1.html'; var safe_token = 'bCkOElraJEU_2F_2B5Elwt_2BdHUdyaorb417l3jtr83FnHFWyg5dkZZwBnF0PbrAdniW8Co6DYFTR1eYJ6fnr'; var body = $('body'); body.on('submit', '#form', function() { var jthis = $(this); var jsubmit = jthis.find('#submit'); jthis.reset(); jsubmit.button('loading'); var postdata = jthis.serializeObject(); $.xpost(jthis.attr('action'), postdata, function(code, message) { if(code == 0) { location.reload(); } else { $.alert(message); jsubmit.button('reset'); } }); return false; }); function resize_image() { var jmessagelist = $('div.message'); var first_width = jmessagelist.width(); jmessagelist.each(function() { var jdiv = $(this); var maxwidth = jdiv.attr('isfirst') ? first_width : jdiv.width(); var jmessage_width = Math.min(jdiv.width(), maxwidth); jdiv.find('img, embed, iframe, video').each(function() { var jimg = $(this); var img_width = this.org_width; var img_height = this.org_height; if(!img_width) { var img_width = jimg.attr('width'); var img_height = jimg.attr('height'); this.org_width = img_width; this.org_height = img_height; } if(img_width > jmessage_width) { if(this.tagName == 'IMG') { jimg.width(jmessage_width); jimg.css('height', 'auto'); jimg.css('cursor', 'pointer'); jimg.on('click', function() { }); } else { jimg.width(jmessage_width); var height = (img_height / img_width) * jimg.width(); jimg.height(height); } } }); }); } function resize_table() { $('div.message').each(function() { var jdiv = $(this); jdiv.find('table').addClass('table').wrap('<div class="table-responsive"></div>'); }); } $(function() { resize_image(); resize_table(); $(window).on('resize', resize_image); }); var jmessage = $('#message'); jmessage.on('focus', function() {if(jmessage.t) { clearTimeout(jmessage.t); jmessage.t = null; } jmessage.css('height', '6rem'); }); jmessage.on('blur', function() {jmessage.t = setTimeout(function() { jmessage.css('height', '2.5rem');}, 1000); }); $('#nav li[data-active="fid-1"]').addClass('active'); </script>