title: How to allow Content-Type header on ubuntu apache
body: <p>I have an Ubuntu server box with apache installed. I'm making a simple web app that keeps track of online friends and let's the user interact with them. I use Commmunigate Pro as a server platform for the whole account management. When I try to send an xml request to Communigate, using the ximss protocol, I get "Request header field Content-Type is not allowed by Access-Control-Allow-Headers" in the chrome console. I'm using javascript for the request. There is a javascript class for ximss, which I know for sure works correctly on other servers. Here is the relevant code:<br>
  //index.php</p>
  
  <pre><code>var ximssSession = {
      serverName : "192.168.1.254:8100",
      theSession : null,
  
      doLogin : function (userName, passWord) {
          console.log("doLogin: "+userName + " " + passWord);
          var params = {
              userName        : userName,
              password        : passWord,
              serverName      : this.serverName,
              loginMethod     : "plain",
              asyncMode       : "syncPOST",
              binding         : "HTTP",
              pollPeriod      : 15
          };
  
          this.theSession = new XIMSSSession(params, this, this.ximssLoginCompleted);
      },
  
      ximssLoginCompleted : function (session, errorCode) {
          console.log("ximssLoginCompleted: "+errorCode);
  
          theSession = session;
  
          theSession.setAsyncProcessor(this, this.ximssAsyncAll,          null,           null, null);
          theSession.setAsyncProcessor(this, this.ximssAsyncSession,      "session",      null, null);
          //theSession.setAsyncProcessor(this, this.ximssAsyncPresence,   "presence",     null, null);
          theSession.setNetworkErrorProcessor(this, this.ximssNetworkErrorProcessor, 10);
  
          theSession.start();
  
          var presenceSetRequest = theSession.createXMLNode("presenceSet");
          presenceSetRequest.setAttribute("presence", "online");
          theSession.sendRequest(presenceSetRequest, this, null, null, false);
  
          var signalBindRequest = theSession.createXMLNode("signalBind");
          signalBindRequest.setAttribute("mode", "kill");
          theSession.sendRequest(signalBindRequest, this, null, this.ximssOpCompleted, true);
      },
  
      ximssAsyncAll : function (xmlData) {
          console.log("ximssAsyncAll: " + (new XMLSerializer()).serializeToString(xmlData));
      },
  
      ximssAsyncSession : function (xmlData) {
          console.log("ximssAsyncSession: " + (new XMLSerializer()).serializeToString(xmlData));
      },
  
      ximssAsyncPresence : function (xmlData) {
          console.log("ximssAsyncPresence: " + (new XMLSerializer()).serializeToString(xmlData));
      },
  
      ximssNetworkErrorProcessor : function (isFatal, timeElapsed) {
          console.log("network error");
      },
  
      ximssOpCompleted : function (errorCode, xmlData){
          console.log("ximssOpCompleted: "+errorCode);
          console.log("ximssOpCompleted: " + (new XMLSerializer()).serializeToString(xmlData));
      }
  };
  
  $(document).ready(function() {
      ximssSession.doLogin(
          &lt;?php echo "\"" . $_SESSION["userName"] . "\"" ?&gt;,
          &lt;?php echo "\"" . $_SESSION["passWord"] . "\"" ?&gt;
      );
  });
  </code></pre>
  
  <p>//ximssclient.js</p>
  
  <pre><code>theSessionRef.startHTTPRequest = function(callback,method,url,body,userName,userPassword) {
    var httpRequest = new XMLHttpRequest();
    if(httpRequest == null) {callback(null,"XMLHttpRequest failed");}
  
    httpRequest.onreadystatechange = function() {
  
      if(httpRequest.readyState != 4) return;
      if(httpRequest.aborted) return;
  
      var errorCode = null;
      var ximssData = null;
      if(httpRequest.status == 0) {
        errorCode = "server communication error";
      } else if(httpRequest.status == 550) {
        errorCode = sessionLost;
      } else if(httpRequest.status &lt; 200 || httpRequest.status &gt;= 300) {
        if((errorCode = httpRequest.statusText) == null) errorCode = "server protocol error";
      } else if(httpRequest.responseXML != null) {
        ximssData = httpRequest.responseXML.childNodes[0];
        if(ximssData.tagName != "XIMSS") {ximssData = null; errorCode = "server XML response is not XIMSS";}
        else if(POSTXMLDocument == null) POSTXMLDocument = httpRequest.responseXML;
      } else {
        if(httpRequest.responseText != null &amp;&amp; httpRequest.responseText != "") errorCode = "server response is not XML";
      }
      callback(ximssData,errorCode);
    }
  
    httpRequest.open(method,url,true,userName,userPassword);
    if(typeof(body) == "string") httpRequest.setRequestHeader("Content-Type","text/xml; charset=utf-8");
    httpRequest.send(body);
    return(httpRequest);
  }
  </code></pre>
  
  <p>This is the start of my console:  </p>
  
  <pre><code>doLogin: *** 1234 index.php:19
  ximssLoginCompleted: null index.php:34
  ximssAsyncSession: &lt;session urlID="94-yzTp9mcoFItifqGR0jBk" userName="***@server.com" random="15C6716184E425E7"/&gt; index.php:59
  ximssAsyncAll: &lt;session urlID="94-yzTp9mcoFItifqGR0jBk" userName="***@server.com" random="15C6716184E425E7"/&gt; index.php:55
  OPTIONS http://192.168.1.254:8100/Session/94-yzTp9mcoFItifqGR0jBk/sync?reqSeq=1&amp;random=1 Request header field Content-Type is not allowed by Access-Control-Allow-Headers. ximssclient.js:426
  XMLHttpRequest cannot load http://192.168.1.254:8100/Session/94-yzTp9mcoFItifqGR0jBk/sync?reqSeq=1&amp;random=1. Request header field Content-Type is not allowed by Access-Control-Allow-Headers. [VM] index.php (223):1
  OPTIONS http://192.168.1.254:8100/Session/94-yzTp9mcoFItifqGR0jBk/sync?reqSeq=1&amp;random=2 Request header field Content-Type is not allowed by Access-Control-Allow-Headers. ximssclient.js:426
  XMLHttpRequest cannot load http://192.168.1.254:8100/Session/94-yzTp9mcoFItifqGR0jBk/sync?reqSeq=1&amp;random=2. Request header field Content-Type is not allowed by Access-Control-Allow-Headers. [VM] index.php (223):1
  OPTIONS http://192.168.1.254:8100/Session/94-yzTp9mcoFItifqGR0jBk/sync?reqSeq=1&amp;random=3 Request header field Content-Type is not allowed by Access-Control-Allow-Headers. ximssclient.js:426
  XMLHttpRequest cannot load http://192.168.1.254:8100/Session/94-yzTp9mcoFItifqGR0jBk/sync?reqSeq=1&amp;random=3. Request header field Content-Type is not allowed by Access-Control-Allow-Headers. [VM] index.php (223):1
  OPTIONS http://192.168.1.254:8100/Session/94-yzTp9mcoFItifqGR0jBk/sync?reqSeq=1&amp;random=4 Request header field Content-Type is not allowed by Access-Control-Allow-Headers. ximssclient.js:426
  XMLHttpRequest cannot load http://192.168.1.254:8100/Session/94-yzTp9mcoFItifqGR0jBk/sync?reqSeq=1&amp;random=4. Request header field Content-Type is not allowed by Access-Control-Allow-Headers. [VM] index.php (223):1
  </code></pre>
  
  <p>I tried adding the line "Header set Acces-Control_Allow_headers" to my virtualhost file and now it looks like this:  </p>
  
  <pre><code>&lt;VirtualHost *:80&gt;
          ServerAdmin webmaster@localhost
  
          DocumentRoot /var/www
          &lt;Directory /&gt;
                  Options FollowSymLinks
                  AllowOverride None
          &lt;/Directory&gt;
          &lt;Directory /var/www&gt;
                  Options Indexes FollowSymLinks MultiViews
                  AllowOverride None
                  Order allow,deny
                  allow from all
                  Header set Access-Control-Allow-Origin "*"
                  Header set Access-Control-Allow-Headers "Content-Type"
          &lt;/Directory&gt;
  
          ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
          &lt;Directory "/usr/lib/cgi-bin"&gt;
                  AllowOverride None
                  Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                  Order allow,deny
                  Allow from all
          &lt;/Directory&gt;
  
          ErrorLog ${APACHE_LOG_DIR}/error.log
  
          # Possible values include: debug, info, notice, warn, error, crit,
          # alert, emerg.
          LogLevel warn
  
          CustomLog ${APACHE_LOG_DIR}/access.log combined
  
      Alias /doc/ "/usr/share/doc/"
      &lt;Directory "/usr/share/doc/"&gt;
          Options Indexes MultiViews FollowSymLinks
          AllowOverride None
          Order deny,allow
          Deny from all
          Allow from 127.0.0.0/255.0.0.0 ::1/128
      &lt;/Directory&gt;
  
  &lt;/VirtualHost&gt;
  </code></pre>
  
  <p>Adding that line did not make any difference (I restarted apache ofcourse). What am I missing here?  </p>
  
  <p>This is my request:  </p>
  
  <pre><code>Request URL:http://192.168.1.254:8100/Session/10-G1cSZuOE75Xo0MNCNcbx/sync?reqSeq=1&amp;random=1
  Request Method:OPTIONS
  Status Code:200 OK
  Request Headersview source
  Accept:*/*
  Accept-Encoding:gzip,deflate,sdch
  Accept-Language:en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4,nl;q=0.2,da;q=0.2
  Access-Control-Request-Headers:origin, content-type
  Access-Control-Request-Method:POST
  Connection:keep-alive
  Host:192.168.1.254:8100
  Origin:http://192.168.1.254
  Referer:http://192.168.1.254/index.php
  User-Agent:Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.71 Safari/537.36
  Query String Parametersview sourceview URL encoded
  reqSeq:1
  random:1
  Response Headersview source
  Access-Control-Allow-Methods:OPTIONS, GET, HEAD, POST, PUT
  Access-Control-Allow-Origin:*
  Access-Control-Max-Age:86400
  Access-Control-Request-Headers:Origin, Content-Type
  Allow:OPTIONS, GET, HEAD, POST, PUT
  Connection:keep-alive
  Content-Length:0
  Content-Type:application/octet-stream
  Date:Sun, 14 Jul 2013 21:41:08 GMT
  Public:OPTIONS, GET, HEAD, POST, PUT
  Server:CommuniGatePro/6.0.5
  </code></pre>
  
  <p>If I just enter the link in the request as url in my browser it succeeds. Are these settings different for GET? Also, when I open the page in IE there are no errors in the console and it reaches the contents of the ximssOpCompleted method.</p>