Turns out the mysterious OPTIONS request we saw when doing a PATCH request is not jDrupal. Browsers do a "pre-flight" OPTIONS request before sending data over the wire to make sure that the target server is going to allow it. The details on when a browser does this pre-flight and when it doesn't are fuzzy. For example, when I do minimal headers on a POST, I don't see a OPTIONS request but trying the same technique for PATCH still results in an OPTIONS request. Maybe there is some way to prevent the pre-flight but I haven't found it yet... Why does this matter? Because the rest module for D8 doesn't support OPTIONS requests. It's listed as the only rest-critical at the moment and the last activity on it was 6 months ago. Per Dries's comment on getting CORS options into the Drupal admin so we don't have to do header() manually in settings.php, it sounds like consensus is that JS apps doing CORS to Drupal are going to have to wait until 8.1 (unless we do something about it).
Turns out the mysterious OPTIONS request we saw when doing a PATCH request is not jDrupal. Browsers do a "pre-flight" OPTIONS request before sending data over the wire to make sure that the target server is going to allow it. The details on when a browser does this pre-flight and when it doesn't are fuzzy. For example, when I do minimal headers on a POST, I don't see a OPTIONS request but trying the same technique for PATCH still results in an OPTIONS request. Maybe there is some way to prevent the pre-flight but I haven't found it yet... Why does this matter? Because the rest module for D8 doesn't support OPTIONS requests. It's listed as the only rest-critical at the moment and the last activity on it was 6 months ago. Per Dries's comment on getting CORS options into the Drupal admin so we don't have to do
header()
manually in settings.php, it sounds like consensus is that JS apps doing CORS to Drupal are going to have to wait until 8.1 (unless we do something about it).