Are schemeless urls like
//blog.flowl.info/
valid in HTTP (rfc?), like in plain HTTP Requests and Responses, or are they only valid in HTML attributes and content ?
HTTP/1.1 302 - Moved
Location: //blog.flowl.info
GET //blog.flowl.info
Update:
I have two contradictionary answers now. Which is correct?
Sidequestion:
Why does the browser even resolve those to:
//blog.flowl.info/
->
http://blog.flowl.info/
instead of:
//blog.flowl.info/
->
http://blog.flowl.info///blog.flowl.info/
They are valid in the Location header field (http://greenbytes.de/tech/webdav/rfc7231.html#header.location).
They are not valid in the request line of an HTTP request.
The browser resolves it this way because this is how relative reference resolution works (http://greenbytes.de/tech/webdav/rfc3986.html#reference-resolution).
As far as I understand protocol/scheme is a mandatory part of an URL and is used by server and intermediate proxies/gateways etc to infer how to handle communication on top of plain TCP/IP. If you are not using http/https but some other well known or even custom protocol, you will have to specify it.
Browser was created for browsing html pages served over HTTP protocol. Hence if you don't specify scheme it automatically defaults it as http. There is also concept of absolute v/s relative URL that you will need to look into how subsequent URLs are resolved by browser.
Related
As you can see from this Bugzilla thread (and also), Firefox does not always send an Origin header in POST requests. The RFC states that it should not be sent in certain undefined "privacy-sensitive" contexts. Mozilla defines those contexts here.
I'd like to know whether these are the only situations in which Firefox will not send the Origin header. As far as I can tell, it also will not send it in cross-origin POST requests (though Chrome and Internet Explorer will), but I can't confirm that in the documentation. Is it enumerated somewhere that I'm missing?
As far as what the relevant specs actually require, the answer has a couple parts:
When browsers must internally set an origin to a value that’ll get serialized as null
When browsers must send the Origin header
Here are the details:
When browsers must set origin to a value that’ll get serialized as null
The HTML spec uses the term opaque origin and defines it as an “internal value”:
with no serialization it can be recreated from (it is serialized as "null" per ASCII serialization of an origin), for which the only meaningful operation is testing for equality
In other words everywhere the HTML spec says opaque origin, you can translate that to null.
The HTML spec requires browsers to set an opaque origin or unique origin in these cases:
Cross-origin images (including cross-origin img elements)
Cross-origin media data (including cross-origin video and audio elements)
Any document generated from a data: URL
Any iframe with a sandbox attribute that doesn’t contain the value allow-same-origin
Any document programmatically created using createDocument(), etc.
Any document that does not have a creator browsing context
Responses that are network errors
The Should navigation response to navigation request of type from source in target be blocked by Content Security Policy? algorithm returns Blocked when executed on a navigate response
The Fetch spec requires browsers to set the origin to a “globally unique identifier” (which basically means the same thing as “opaque origin” which basically means null…) in one case:
Redirects across origins
The URL spec requires browsers to set an opaque origin in the following cases:
For blob: URLs
For file: URLs
For any other URLs whose scheme is not one of http, https, ftp, ws, wss, or gopher.
But note that just because the browser has internally set an opaque origin—essentially null—that doesn’t necessarily mean the browser will send an Origin header. So see the next part of this answer for details about when browsers must send the Origin header.
When browsers must send the Origin header
Browsers send the Origin header for cross-origin requests initiated by a fetch() or XHR call, or by an ajax method from a JavaScript library (axios, jQuery, etc.) — but not for normal page navigations (that is, when you open a web page directly in a browser), and not (normally) for resources embedded in a web page (for example, not for CSS stylesheets, scripts, or images).
But that description is a simplification. There are cases other than cross-origin XHR/fetch/ajax calls when browsers send the Origin header, and cases when browsers send the Origin header for embedded resources. So what follows below is the longer answer.
In terms of the spec requirements: The spec requires the Origin header to be sent only for any request which the Fetch spec defines as a CORS request:
A CORS request is an HTTP request that includes an Origin header. It cannot be reliably identified as participating in the CORS protocol as the Origin header is also included for all requests whose method is neither GET nor HEAD.
So, what the spec means there is: The Origin header is sent in all cross-origin requests, but it’s also always sent for all POST, PUT, PATCH, and DELETE requests — even for same-origin POST, PUT, PATCH, and DELETE requests (which by definition in Fetch are actually “CORS requests” — even though they’re same-origin).*
The other cases when browsers must send the Origin header are any cases where a request is made with the “CORS flag” set — which, as far as HTTP(S) requests, is except when the request mode is navigate, websocket, same-origin, or no-cors.
XHR always sets the mode to cors. But with the Fetch API, those request modes are the ones you can set with the mode field of the init-object argument to the fetch(…) method:
fetch("http://example.com", { mode: 'no-cors' }) // no Origin will be sent
Font requests always have the mode set to cors and so always have the Origin header.
And for any element with a crossorigin attribute (aka “CORS setting attribute”), the HTML spec requires browsers to set the request mode to cors (and to send the Origin header).
Otherwise, for embedded resources — any elements having attributes with URLs that initiate requests (<script src>, stylesheets, images, media elements) — the mode for the requests defaults to no-cors; and since those requests are GET requests, that means, per-spec, browsers send no Origin header for them.
When HTML form elements initiate POST requests, the mode for those POSTs also defaults to no-cors — in the same way that embedded resources have their mode defaulted to no-cors. However, unlike the no-cors mode GET requests for embedded resources, browsers do send the Origin header for those no-cors mode POSTs initiated from HTML form elements.
The reason for that is, as mentioned earlier in this answer, browsers always send the Origin header in all POST, PUT, PATCH, and DELETE requests.
Also, for completeness here and to be clear: For navigations, browsers send no Origin header. That is, if a user navigates directly to a resource — by pasting a URL into a browser address bar, or by following a link from another web document — then browsers send no Origin header.
* The algorithm in the Fetch spec that requires browsers to send the Origin header for all CORS requests is this:
To append a request Origin header, given a request request, run these steps:
1. Let serializedOrigin be the result of byte-serializing a request origin with request.
2. If request’s response tainting is "cors" or request’s mode is "websocket", then
append Origin/serializedOrigin to request’s header list.
3. Otherwise, if request’s method is neither GET nor HEAD,
then: [also send the Origin header in that case too]
Step 2 there is what requires the Origin header to be sent in all cross-origin requests — because all cross-origin requests have their response tainting set to "cors".
But step 3 there requires the Origin header to also be sent for same-origin POST, PUT, PATCH, and DELETE requests (which by definition in Fetch are actually “CORS requests” — even though they’re same-origin).
The above describes how the Fetch spec currently defines the requirements, due to a change that was made to the spec on 2016-12-09. Up until then the requirements were different:
• previously no Origin was sent for a same-origin POST
• previously no Origin was sent for cross-origin POST from a <form> (without CORS)
So the Firefox behavior the question describes is what the spec previously required, not what it currently requires.
For me this was happening on a super-standard form POST to a relative URL on localhost, and seems to have been triggered by having
<meta name="referrer" content="no-referrer">
in the <head>.
Changing it to
<meta name="referrer" content="same-origin">
seemed to make Firefox happier.
This question is about HTTP Request headers -- not HTTP Response headers.
Is there any way to programmatically make User Agents add or change any HTTP Request Header e.g. by means of HTML, JavaScript, for links or resources from a web page. There exists some HTTP Request Headers that one would think should be able to be controlled programmatically, for example max-stale.
(One could for example imagine that some optional attribute for HTML-elements <a>, <link>, <img> <script> etc, could exist that would cause the User Agent to add/change a HTTP request header in its request to the server, but I have not found such an attribute. Similarly, one could think that there should exist some mechanism to control HTTP Request Headers when AJAX is used.)
Turning around the question ...: Why does the HTTP Request Header max-stale exist at all if it cannot be controlled?
Thanks!
The XMLHTTPResponse setRequestHeader() method can be used to set HTTP request headers for an AJAX request. Various JavaScript libraries expose this function in different ways. For example, with jQuery.ajax() you would set the headers property of the settings parameter.
There are some ways in which you can affect request headers in html, e.g. via a form's enctype attribute. I do not believe there is any way to actually specify the actual header values in html.
For Ajax you can specify request headers, though the browser will block certain headers from being set, I doubt max-stale is one of them.
Also not only browsers make http request, there are a whole host of applications that do and any of them could easily set the max-stale header if they wanted.
Let's say I have the following IFRAME. It works fine as long as the browser is viewing the page using HTTP, however, if the browser is viewing the page using HTTPS, it will result in errors, and the IFRAME must be changed to also use HTTPS.
<iframe id="sitePreview" name="sitePreview" src="http://preview.administrator.test6.example.com/index.php?cid=17&preview=1330668404"></iframe>
Without using server script to customize the protocol of the HTML based on the protocol being used to view the page, is it possible to create the URI so that they will work with both HTTP and HTTPS?
Also, please comment if this applies to other links such as:
<img alt="Map" src="http://maps.google.com/maps/api/staticmap?markers=color:blue|31 Milk St Boston MA&zoom=14&size=400x400&sensor=false" class="map">
<script src="http://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=places" type="text/javascript"></script>
Keep in mind cross site iframe calls can be tricky, read this article:
http://blog.cakemail.com/the-iframe-cross-domain-policy-problem/, however, since it does load, I'm assuming you are including an iframe from the same domain.
To answer your question, simply drop the protocol off the src, you would reference it as:
<iframe id="sitePreview" name="sitePreview" src="//preview.administrator.test6.example.com/index.php?cid=17&preview=1330668404"></iframe>
This will make sure that it will use whatever protocol the parent is using...
You could also hardcode it to https, but that would mean that every request will serve a secure image which creates unnecessary overhead...
I think this would work:
If(location == "https://whatever.com")
{
//this is https
}
Else
{
//it's http
}
Let me know if I didn't get it right and I will recode it.
We have an ecommerce website that displays groups of products by category using a URL format that maps almost exactly to the REST URL format we would like to use for our forthcoming API.
e.g. example.com/products/latest or example.com/products/hats
Is it a valid pattern to use the same URL for visible (HTML) and invisible (JSON) results, and to use the Accept http request header to determine what should be returned.
i.e. if you call example.com/products/latest with Accept: application/json you get just the product data, but if you use text/html you get the full HTML page (header, footer, site chrome etc.)
And if so, is this a good idea - will we run into problems if, for instance, the website needs to change, but the API needs to be stable?
UPDATE: some helpful resources - here is an article[1] by Peter Williams discussing the use of the HTTP Accept header to version APIs, and I have also referenced an SO question[2] that reveals some of the problems of using this approach. Probably better to use a custom HTTP header?
[1] Making the case for using Accept: http://barelyenough.org/blog/2008/05/versioning-rest-web-services/
[2] Problems with jQuery (& IE): Cannot properly set the Accept HTTP header with jQuery
[3] Making the case for using Accept: http://blog.steveklabnik.com/2011/07/03/nobody-understands-rest-or-http.html
[4] Sitting on the fence: http://www.informit.com/articles/article.aspx?p=1566460
Using http headers is generally becoming the accepted way of determining this.
In ASP.NET MVC for example there is an IsAjaxRequest method that checks for the X-Requested-With header and if it is equal to "XMLHttpRequest" it is deemed to be an ajax request.
Last time I tried to do that (and this was a few years ago) I found I could not override the Accept header of an XMLHttpRequest object in Opera. If that isn't a worry for you, then go for it, that is how HTTP was designed to work.
I recommend setting your HTML response to have a higher q value then your JSON response though, some browsers send Accept: */*.
I have no experience with this, but Restful Web Services recommends that you version your API via the URL (e.g. api.example.com/v1/products/hats) — I’m not sure that would fit with using the same URLs for the website and the API.
i wonder if there is some way to do something like that:
If im on a specific site i want that some of javascript files to be loaded directly from my computer (f.e. file:///c:/test.js), not from the server.
For that i was thinking if there is a possibility to make an extension which could change HTML code in a response which browser gets right before displaying it. So whole process should look like that:
request is made
browser gets response from server
#response is changed# - this is the part when extension comes in
browser parse changed response and display page with that new response.
It doesnt even have to be a Chrome extension anyway. It should just do the job described above. It can block original file and serve another one (DNS/proxy?) or filter whole HTTP traffic in my computer and replace specific code to another one of matched response.
You can use the WebRequest API to achieve that. For example, you can add a onBeforeRequest listener and redirect some requests:
chrome.webRequest.onBeforeRequest.addListener(function(details)
{
var responseData = "<div>Some text</div>"
return {redirectUrl: "data:text/html," + encodeURIComponent(responseData)};
}, {urls: ["https://www.google.com/"]}, ["blocking"]);
This will display a <div> element with the text "some text" instead of the Google homepage. Note that you can only redirect to URLs that the web server itself is allowed to redirect to. This means that redirecting to file:/// URLs is not possible, and you can only redirect to files inside your extension if these are web accessible. data: and http: URLs work fine however.
In Windows you can use the Proxomitron (proxomitron.info) which is a local proxy that can intercept any page or file being loading into your browser and change it using regular expressions (no DOM parsing) however you want, before it is rendered by the browser.