PHP Nhận giao thức URL trang web - http so với https


197

Tôi đã viết một chức năng nhỏ để thiết lập giao thức url của trang hiện tại nhưng tôi không có SSL và không biết cách kiểm tra nếu nó hoạt động theo https. Bạn có thể cho tôi biết nếu điều này là chính xác?

function siteURL()
{
    $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
    $domainName = $_SERVER['HTTP_HOST'].'/';
    return $protocol.$domainName;
}
define( 'SITE_URL', siteURL() );

Có cần thiết phải làm như trên không hoặc tôi có thể làm như thế không?:

function siteURL()
{
    $protocol = 'http://';
    $domainName = $_SERVER['HTTP_HOST'].'/'
    return $protocol.$domainName;
}
define( 'SITE_URL', siteURL() );

Trong SSL, không phải máy chủ sẽ tự động chuyển đổi url thành https ngay cả khi url thẻ neo đang sử dụng http? Có cần thiết phải kiểm tra giao thức không?

Cảm ơn bạn!


1
Sẽ không phải là một lựa chọn tốt hơn cho bạn để cài đặt một máy chủ web cục bộ và ném chứng chỉ SSL tự ký vào đó chứ? Bằng cách đó bạn có thể tự kiểm tra nó.
Frazell Thomas

Vâng, điều đó thật tuyệt vời, nhưng tôi không biết làm thế nào để làm điều đó.

4
Mặc dù điều này không trả lời câu hỏi của bạn, nhưng một giải pháp tốt hơn cho vấn đề của bạn (mặc dù tôi không thể chắc chắn mà không biết thêm) có thể sử dụng URL Giao thức tương đối .
Reese Moore

Chỉ cần một câu hỏi nhanh ... tại sao bạn lại thực hiện một chức năng nếu nó không năng động. Nó không giống như bạn cho nó ăn bất kỳ lọ nào để thay đổi url. Tại sao không định nghĩa một hằng số? Đó là những gì tôi đã làm. $ Protocol = (! trống ($ _ SERVER ['HTTPS']) && $ _SERVER ['HTTPS']! == 'tắt' || $ _SERVER ['SERVER_PORT'] == 443)? "https: //": "http: //"; định nghĩa ('SITE_URL', $ giao thức. $ _ SERVER ['HTTP_HOST']. '/');
HTMLGuy

Câu trả lời:



86

Tôi biết rằng đã muộn, mặc dù có một cách thuận tiện hơn nhiều để giải quyết loại vấn đề này! Các giải pháp khác khá lộn xộn; đây là cách tôi sẽ làm điều đó:

$protocol = stripos($_SERVER['SERVER_PROTOCOL'],'https') === 0 ? 'https://' : 'http://';

... hoặc thậm chí không có điều kiện nếu bạn thích:

$protocol = strtolower(substr($_SERVER["SERVER_PROTOCOL"],0,strpos( $_SERVER["SERVER_PROTOCOL"],'/'))).'://';

Có một cái nhìn $_SERVER["SERVER_PROTOCOL"]


20
Việc dont này với "https" stackoverflow.com/questions/16825243/...
wormhit

@wormhit nó chủ yếu phụ thuộc vào cách máy chủ web của bạn được cấu hình mặc dù
Ivo

Bất kỳ lý do tại sao bạn sử dụng striposthay vì strpos?
Fred

12
$_SERVER['SERVER_PROTOCOL']được tạo để lưu trữ HTTP/1.0hoặc HTTP/1.1tùy thuộc vào phiên bản giao thức, bạn nói về loại cấu hình máy chủ HTTP nào, lưu trữ httpsthông tin về chuỗi này đến từ truy vấn http?
regilero

1
Không hoạt động trong trường hợp của tôi! $ _SERVER ['SERVER_PROTOCOL'] chứa "HTTP" (không có bất kỳ "S" nào) trong khi giao thức là https. Kiểm tra $ _SERVER ['HTTPS'] là phù hợp hơn.
Simon Hi

68

Điều này làm việc cho tôi

if (isset($_SERVER['HTTPS']) &&
    ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) ||
    isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
    $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
  $protocol = 'https://';
}
else {
  $protocol = 'http://';
}

3
Đây là giải pháp hoạt động nếu sử dụng proxy (như trong trường hợp của tôi là CloudFlare)
Jesús Carrera

1
Điều này là chính xác - bạn không nên sử dụng https chỉ vì bạn đang sử dụng cổng 443.
Đánh dấu

24

Một vài thay đổi:

function siteURL() {
  $protocol = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || 
    $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
  $domainName = $_SERVER['HTTP_HOST'];
  return $protocol.$domainName;
}

16

Cách ngắn

$scheme = $_SERVER['REQUEST_SCHEME'] . '://';

3
REQUEST_SCHEMEkhông đáng tin cậy
Farnabaz

5
REQUEST_SCHEME không khả dụng cho đến khi Apache 2.4.
KenB

7

Bởi vì kiểm tra số cổng không phải là một thực hành tốt theo tôi, giải pháp của tôi là:

define('HTTPS', isset($_SERVER['HTTPS']) && filter_var($_SERVER['HTTPS'], FILTER_VALIDATE_BOOLEAN));

Các HTTPSlợi nhuận liên tục TRUEnếu $_SERVER['HTTPS']được thiết lập và tương đương với "1", "true", "trên" hoặc "có". Trả về SAI nếu không.


Đây có lẽ là câu trả lời tốt nhất. Rất nhiều câu trả lời sẽ chỉ trong một tỷ lệ phần trăm các tình huống. Ví dụ: mọi người chỉ kiểm tra xem $ _SERVER ['HTTPS'] đã được đặt chưa. Nhiều khung đặt biến này là sai hoặc 'tắt', v.v., do đó kiểm tra xem nó có đơn giản là không hoạt động không.
Daniel Dewhurst

1
Mặc dù điều này hoạt động trong hầu hết các tình huống, đã có lúc SNAFU có cấu hình và $ _SERVER ['HTTPS'] thực sự được đặt thành "tắt". Mã của bạn vẫn coi đó là "vượt qua" bài kiểm tra, do đó nên được sửa đổi để cho phép cài đặt cụ thể đó.
Dave Morton

6

Đối với bất kỳ hệ thống nào ngoại trừ IIS, điều này là khá đủ để xác định URL tự trang web:

$siteURL='http'.(empty($_SERVER['HTTPS'])?'':'s').'://'.$_SERVER['HTTP_HOST'].'/';

hoặc là

$siteURL='http'.(empty($_SERVER['HTTPS'])?'':'s').'://'.$_SERVER['SERVER_NAME'].'/';

phụ thuộc vào chính xác những gì bạn muốn: HTTP_HOST so với SERVER_NAME


5

Trong trường hợp proxy, SERVER_PORTcó thể không cung cấp giá trị chính xác vì vậy đây là những gì làm việc cho tôi -

$protocol = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') || $_SERVER['SERVER_PORT'] == 443 || $_SERVER['HTTP_X_FORWARDED_PORT'] == 443) ? "https://" : "http://"

4

Sử dụng biến máy chủ này để lấy chi tiết giao thức:

 $scheme = $_SERVER['REQUEST_SCHEME'] . '://';
 echo $scheme; //it gives http:// or https://

Lưu ý rằng biến máy chủ này không đáng tin cậy. Để biết thêm thông tin, hãy xem: $ _SERVER ['REQUEST_SCHEME'] có đáng tin cậy không?


Bạn có thể thêm một số thông tin vào bài viết của bạn, và không chỉ mã? Ví dụ giải thích tại sao đây là một câu trả lời cho câu hỏi?
ndsmyter

3

Tôi biết đây là một câu hỏi cũ nhưng tôi đã gặp nó ngày hôm nay vì tôi cần kiểm tra điều này trong trang web của mình. Có vẻ như các câu trả lời ở trên là phức tạp không cần thiết. Để thiết lập giao thức trang web, tất cả những gì bạn phải làm là kiểm tra$_SERVER['HTTPS']

Nếu giao thức đang sử dụng HTTPS, thì $_SERVER['HTTPS']sẽ trả về 'bật'. Nếu không, biến sẽ vẫn trống. Ví dụ:
// test if HTTPS is being used. If it is, the echo will return '$SSL_test: on'. If not HTTPS, '$SSL_test' will remain empty.

$SSL_test = $_SERVER['HTTPS'];

echo '<p>$SSL_test: '.$SSL_test.'</p>';

if($SSL_test == true) {
    echo 'You\'re using SSL';
} else {
    echo 'You\'re not using SSL';
} 

Bạn có thể sử dụng cách trên để kiểm tra HTTPS dễ dàng và gọn gàng và thực hiện theo đó. :)


2
Không phải mọi máy chủ đều có $ _SERVER ['HTTPS']
ChrisDeDavidMindflowAU

2

đã thực hiện một chức năng bằng cách sử dụng câu trả lời của Rid Iculous hoạt động trên hệ thống của tôi.

function site_protocol() {
    if(isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&  $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')  return $protocol = 'https://'; else return $protocol = 'http://';
}

Hy vọng nó giúp


2

Tôi đã kiểm tra câu trả lời được bình chọn nhiều nhất và nó không hiệu quả với tôi , cuối cùng tôi đã sử dụng:

$protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';

Một số máy chủ web không hỗ trợ $_SERVER["HTTPS"]và do đó mã của bạn có thể quay lại http://ngay cả khi nó phải làhttps://
nathanfranke

Nếu máy chủ không hỗ trợ https, tại sao mã vẫn trả về https?
CONvid19

Máy chủ của tôi hỗ trợ https nhưng $_SERVER["HTTPS"]biến không bao giờ được xác định.
nathanfranke

Tôi bối rối bởi 2 bình luận của bạn. Có lẽ tốt hơn nếu bạn tạo một câu trả lời mới bao gồm những trường hợp đặc biệt đó. Cảm ơn và chúc may mắn!
CONvid19

2
$protocal = 'http';
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' || $_SERVER['HTTPS'] == 'on') {$protocal = 'https';}


echo $protocal;

2

Trích xuất từ ​​CodeIgniter:

if ( ! function_exists('is_https'))
{
    /**
     * Is HTTPS?
     *
     * Determines if the application is accessed via an encrypted
     * (HTTPS) connection.
     *
     * @return  bool
     */
    function is_https()
    {
        if ( ! empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off')
        {
            return TRUE;
        }
        elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https')
        {
            return TRUE;
        }
        elseif ( ! empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off')
        {
            return TRUE;
        }

        return FALSE;
    }
}

0

đó là giải pháp tốt nhất của https hoặc http sử dụng điều này:

<?php
$protocol = '//';  
$site_url = $protocol.$_SERVER["HTTP_HOST"];
?>

Nhưng không thể hiển thị https hoặc http, vì vậy nó chỉ sử dụng để liên kết nội dung trang web của bạn như hình ảnh, v.v.

nếu muốn chuyển hướng trang web của bạn trong https, hãy thêm mã này vào tệp .htaccess:

<IfModule mod_rewrite.c>
 RewriteCond %{HTTP:CF-Visitor} '"scheme":"http"'
 RewriteRule ^(.*)$ https://www.your-domain.com$1 [L]
</IfModule>

Thay đổi www.your-domain.com bằng tên dowmain của bạn.


0

Dưới đây là cách tôi làm điều đó ... nó là một viết tắt if else phiên bản thoát khỏi Iculous của câu trả lời ...

$protocol = isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] === 1) || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ? 'https' : 'http';

0

Tôi nghĩ rằng func hoàn chỉnh sẽ trông giống như:

function siteURL()
{
    $protocol =  "http://";
    if (
        //straight
        isset($_SERVER['HTTPS']) && in_array($_SERVER['HTTPS'], ['on', 1])
        ||
        //proxy forwarding
        isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https'
    ) {
        $protocol = 'https://';
    }

    $domainName = $_SERVER['HTTP_HOST'];
    return $protocol . $domainName;
}

Ghi chú:

  • bạn cũng nên tìm HTTP_X_FORWARDED_PROTO (ví dụ: nếu máy chủ proxy)
  • dựa vào cổng 443 không an toàn (https có thể được phục vụ trên các cổng khác nhau)
  • REQUEST_SCHEME không đáng tin cậy

0

Tôi biết rằng tôi đến hơi muộn với bữa tiệc này, nhưng nếu bạn không thích sử dụng $ _SERVER vì nó không được khuyến khích và thậm chí đã hủy kích hoạt trên một số khung công tác PHP; bạn có một máy chủ web apache, do đó bạn có thể sử dụng lệnh gốc của nó: -

$protocol = apache_getenv('HTTPS') ? 'https:' : 'http:';
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.